package ac.qnlm.listener;

import ac.qnlm.antlr.CPP14BaseListener;
import ac.qnlm.antlr.CPP14Lexer;
import ac.qnlm.antlr.CPP14Parser;
import ac.qnlm.util.Utility;
import ac.qnlm.util.Utility.pointerDataAttr;
import ac.qnlm.util.Utility.dataPattern;
import org.antlr.v4.runtime.BufferedTokenStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

public class firstTraverseListener extends CPP14BaseListener{

    private BufferedTokenStream Cpptokens;
    private Utility utility = new Utility();

    private boolean swPredefineAlreadyIn = false;

    private pointerDataAttr paraVarAttr  = new pointerDataAttr();

    private pointerDataAttr atomAttr  = new pointerDataAttr();

    private dataPattern dataPatterns = new dataPattern();

    private List<Utility.dataPattern> dataPatternList  = new ArrayList<>();

    private Utility.directive directiveDef = new Utility.directive();

    //flag that indicates we could add dma transfer code by now
    private boolean dmaTrans = false;

    private static Logger logger = LogManager.getLogger(firstTraverseListener.class.getName());
    public ParseTreeProperty<String> classout = new ParseTreeProperty<String>();
    public String getclass(ParseTree ctx) { return classout.get(ctx); }
    public void setclass(ParseTree ctx, String s) { classout.put(ctx, s); }

    public firstTraverseListener(CPP14Parser parser, Utility util, CommonTokenStream token) {

        //super();
        Cpptokens = token;
        utility = util;
    }

    private void atomCorePartition(){
        //default setting for without atomic operation
        int cpCore = 64;
        int rcvCore = 0;
        int rmadata = 1;
        // to define the number of cp_core and rcv_core
        if(directiveDef.isAtomOpr()){
            rcvCore = atomAttr.getRcvCoreNum();
            rmadata = atomAttr.getRmaDataNum();
            cpCore  = 64 - rcvCore;
        }
        utility.dynamicDef.add("\n#define CP_CORE      " + cpCore);
        utility.dynamicDef.add("\n#define RCV_CORE     " + rcvCore);
        utility.dynamicDef.add("\n#define DATAPAKAGE   " + rmadata + "\n");
        if(directiveDef.isAtomOpr()){
            //dynamic global definition
            utility.dynamicDef.add("\n//RMA communication API");
            utility.dynamicDef.add("\n#define remote_ldm_addr(slaveid,ldm_var)    ((unsigned long)&ldm_var|((unsigned long)slaveid<<20)|(1ULL<<45))");
            utility.dynamicDef.add("\n//remoteVal contains value and position in each compute core");
            utility.dynamicDef.add("\n__thread_local volatile "+ atomAttr.getType() +
                    "   remoteVal[CP_CORE][DATAPAKAGE*2]   __attribute__ ((aligned(64))) = {0};");
            utility.dynamicDef.add("\n//atomic local variables in each compute core");
            utility.dynamicDef.add("\n__thread_local volatile "+ atomAttr.getType() + " " +
                    atomAttr.getVariable() + "Val[RCV_CORE][DATAPAKAGE*2]      __attribute__ ((aligned(64))) = {0};\n");
            //organize send_data_to_rcv_core function for variable type
            utility.atomsendDataFunc.add("\nvoid send_data_to_rcv_core(int targetCore, int dataSize, volatile " +
                    atomAttr.getType() + " *localData, volatile " + atomAttr.getType() + " *remoteData, volatile int *remote_rply)");
            utility.atomsendDataFunc.add("\n{\n" +
                    "    int targetid = targetCore + CP_CORE;\n" +
                    "    while(1)\n" +
                    "    {\n" +
                    "        cpt_rply = (volatile int*)remote_ldm_addr(targetid, *remote_rply);\n" +
                    "        if(*cpt_rply == 0)\n" +
                    "            break;\n" +
                    "    }\n" +
                    "    CRTS_rma_iput(localData,&l_rply,dataSize,targetid,remoteData,remote_rply);\n" +
                    "    while (l_rply!=1);\n" +
                    "    l_rply = 0;\n" +
                    "}\n");
            //organize receiving_core_get_data function
            utility.atomRcvCoreFunc.add("\nvoid receiving_core_get_data(" + atomAttr.getType() +
                    " *hostData,int dma_Size, int Stride) {\n");
            utility.atomRcvCoreFunc.add("\n    " + atomAttr.getType() + " *localData = ("+  atomAttr.getType()
                    + " *)ldm_malloc(sizeof(" + atomAttr.getType() + ") * dma_Size);");
            if(atomAttr.isCopyin())
                utility.atomRcvCoreFunc.add("\n    CRTS_dma_iget(localData, hostData, sizeof(int) * dma_Size, &dma_rply);\n" +
                        "    D_COUNT++;\n" +
                        "    CRTS_dma_wait_value(&dma_rply, D_COUNT);");

            utility.atomRcvCoreFunc.add("\n    int localPos;\n" +
                    "    int end = 0;\n" +
                    "\n" +
                    "    while(1)\n" +
                    "    {\n" +
                    "        for(int i = 0; i < CP_CORE; i++)\n" +
                    "        {\n" +
                    "            if(rw_rply[i] == 1)\n" +
                    "            {\n" +
                    "                for(int j = 0; j < DATAPAKAGE; j++)\n" +
                    "                {   \n" +
                    "                    int posTemp = (int)remoteVal[i][j*2+1];\n" +
                    "                    // get locations from RMA\n" +
                    "                    localPos = posTemp - (blockIndex - CP_CORE) * Stride;\n" +
                    "                    // do calculation\n" +
                    "                    localData[localPos] += remoteVal[i][j * 2 + 0];\n" +
                    "                }\n" +
                    "                // reset the flags\n" +
                    "                rw_rply[i] = 0;\n" +
                    "            }\n" +
                    "            // judge if need to end loop\n" +
                    "            if(r_end[i] == 1)\n" +
                    "            {\n" +
                    "                end++;\n" +
                    "                r_end[i] = 0;\n" +
                    "            }\n" +
                    "        }\n" +
                    "        if(end == CP_CORE)\n" +
                    "            break;\n" +
                    "    }\n" +
                    "    CRTS_dma_iput(hostData, localData, sizeof(int) * dma_Size, &dma_rply);\n" +
                    "    D_COUNT++;\n" +
                    "    CRTS_dma_wait_value(&dma_rply, D_COUNT);");

            utility.atomRcvCoreFunc.add("\n    ldm_free(localData, sizeof(" + atomAttr.getType() +
                    ") * dma_Size);\n" +
                    "}\n");
        }
    }

    @Override public void exitTranslationunit(CPP14Parser.TranslationunitContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.declarationseq()!=null) {
            String args = getclass(ctx.declarationseq());
            buftree.append(args);
            setclass(ctx, buftree.toString());

            logger.info("enterTranslationunit final\t\n" + args);
        }
    }

    @Override public void exitDeclarationseq(CPP14Parser.DeclarationseqContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(getclass(ctx.declarationseq())!=null){
            String args = getclass(ctx.declarationseq());
            buftree.append(args);
            //	logger.info("declarationseq111\t\n" + args);

        }

        if(getclass(ctx.declaration())!=null) {
            String args = getclass(ctx.declaration());

            //add openacc directive from PRAGMA channel
            Token semi = ctx.getStop();
            int i = semi.getTokenIndex();

            List<Token> pragmaChannel = Cpptokens.getHiddenTokensToRight(i, CPP14Lexer.PRAGMA);
            if(pragmaChannel!=null){
                for(int j=0; j<pragmaChannel.size();j++){
                    Token cmt = pragmaChannel.get(j);
                    buftree.append("\t" + cmt.getText()+"\t\n");
                    utility.includedefinelist.add(cmt.getText());
                    logger.info("getHiddenTokensToRightPRAGMA1111\t\n" + cmt.getText());
                }
            }

            buftree.append(args);

        }
        utility.globalScopeDef.setScope(Utility.globalScope.glbScope.NONE);

        setclass(ctx, buftree.toString());
        logger.info("exitDeclarationseq final\t\n" + getclass(ctx));
    }

    @Override public void exitDeclaration(CPP14Parser.DeclarationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(getclass(ctx.blockdeclaration())!=null) {
            String args = getclass(ctx.blockdeclaration());
            setclass(ctx, args);
            logger.info("blockdeclaration\t\n" + args);

        }
        if(ctx.functiondefinition()!=null) {
            String args = getclass(ctx.functiondefinition());
            setclass(ctx, args);
            logger.info("functiondefinition\t\n" + args);
        }
        if(ctx.templatedeclaration()!=null) {
            String args = getclass(ctx.templatedeclaration());
            setclass(ctx, args);
            logger.info("templatedeclaration Declaration\t\n" +args);
        }
        if(ctx.explicitspecialization()!=null){
            String args = getclass(ctx.explicitspecialization());
            setclass(ctx, args);
            logger.info("explicitspecialization Declaration\t\n" +args);
        }

        //todo : name space parse, to do later....
		/*
		if(ctx.namespacedefinition()!=null) {
			String args = tokens.getText(ctx.namespacedefinition());
			logger.info("namespacedefinition\t\n" + args);
		}
		*/
    }

    @Override public void exitFunctiondefinition(CPP14Parser.FunctiondefinitionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        // add kernelFunc parameter declaration before the kernel entry function
        //if(utility.currentscope.equals(Utility.GlbScope.KERNERENTRY)){
        if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)){
            buftree.append("typedef struct kernelPara{\n");
            for(int i=0; i<utility.kernelPara.size(); i++)
                buftree.append("\t" + utility.kernelPara.get(i) + ";\n");
            buftree.append("\n}Para;\n\n");

            for(int j=0; j<utility.dynamicDef.size(); j++)
                buftree.append(utility.dynamicDef.get(j));

            if(directiveDef.isAtomOpr())
                for(int j=0; j<utility.atomicDef.size(); j++)
                    buftree.append(utility.atomicDef.get(j));

            //add athread global variable definition
            for (int j = 0; j < utility.globalDef.size(); j++)
                buftree.append(utility.globalDef.get(j));

            if(directiveDef.isAtomOpr()) {
                buftree.append(utility.writeConflictInit);

                for (int j = 0; j < utility.atomsendDataFunc.size(); j++)
                    buftree.append(utility.atomsendDataFunc.get(j));

                buftree.append(utility.finshDataSending);

                for (int j = 0; j < utility.atomRcvCoreFunc.size(); j++)
                    buftree.append(utility.atomRcvCoreFunc.get(j));
            }

            logger.info("kernelPara declaration"+buftree.toString());
        }
        if(ctx.declspecifierseq()!=null){
            String args = getclass(ctx.declspecifierseq());
            buftree.append(args+" ");
            logger.info("exitFunctiondefinition declspecifierseq "+args);
        }
        if(ctx.declarator() != null){
            String args = getclass(ctx.declarator());
            buftree.append(args);
            logger.info("exitFunctiondefinition declarator "+args);
        }
        if(ctx.functionbody()!=null){
            String args = getclass(ctx.functionbody());
            buftree.append("{\t\n"+args+ "\n}\n");
            logger.info("exitFunctiondefinition functionbody "+args);
        }

        setclass(ctx, buftree.toString());
    }

    @Override
    public void exitFunctionbody(CPP14Parser.FunctionbodyContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.ctorinitializer()!=null){
            String args = ctx.ctorinitializer().getText();
            logger.info("ctorinitializer\t\n"+args);
        }

        if(ctx.compoundstatement()!=null){
            String args = getclass(ctx.compoundstatement());
            // add ATHREAD local variable definition and basic operation
            //if(utility.currentscope.equals(Utility.GlbScope.KERNERENTRY)){
            if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)){
                for(int i=0; i<utility.athreadLocalVar.size(); i++)
                    buftree.append(utility.athreadLocalVar.get(i));
                for(int i=0; i<utility.athreadBasicOp.size(); i++)
                    buftree.append(utility.athreadBasicOp.get(i));
                //atomic specific operation
                if(directiveDef.isAtomOpr()){
                    buftree.append("\n    write_conflict_init(" + atomAttr.getDataSize() +
                            ", &dmaSize,&dataStride);");
                    buftree.append("\n    if(blockIndex < CP_CORE) {\n");
                }

                // according domain specific language to do the dma transfer
                // principle: if readonly, data size < 128K, dma directly

                for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                    pointerDataAttr data = utility.pointerDataAttrList.get(i);

                    if(data.getAttribute().equals("readonly") && data.getldmByDma()){
                        buftree.append("  " + data.getType() + "* " + data.getVariable() + "_s = (" +
                                data.getType() + "*)ldm_malloc(" + data.getDataSize() + ");\n");
                        buftree.append("  CRTS_dma_iget(" + data.getVariable() +"_s, Para_s->" + data.getVariable() +
                                ", " + data.getDataSize() + ", &dma_rply);\n");
                        buftree.append("  D_COUNT++;\n" + "  CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }
                }
                // append block affine mechanism
                buftree.append(utility.blockAffineTrans);
                // if inout or outonly, we need to allocate and transfer data according the thread sizes
                // by this way, the data should be transferred by stride
                for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                    pointerDataAttr data = utility.pointerDataAttrList.get(i);
                    logger.info("data arrangement " + i + " type: " + data.getType() + " var: " + data.getVariable()
                            + " size: " + data.getDataSize() + " attr: " + data.getAttribute() + " dmaWithStride: "
                            + data.getdmaWithStride() + " ldmByDma: " + data.getldmByDma() + " GlbSharedMem: "
                            + data.getglbSharedMem());

                    if(data.getAttribute().equals("inout")){
                        if(data.getglbSharedMem()){
                            // global shared variable definition and transfer
                            String datasize = data.getDataSize();
                            if(datasize.contains("*"))
                                datasize = datasize.substring(datasize.indexOf("*")+1);
                            logger.info("datasize: " + datasize);
                            utility.globalDef.add("__thread_local_share volatile " + data.getType() + " " + data.getVariable() +
                                    "_s[" + datasize + "]    __attribute__ ((aligned(64))) = { 0 };\n\n");
                            buftree.append("    CRTS_memcpy_sldm(" + data.getVariable() + "_s, Para_s->" +
                                    data.getVariable() + ", " + data.getDataSize() + ", MEM_TO_LDM);\n\n");
                        }
                        else {
                            buftree.append("  " +data.getType() + " *"+ data.getVariable() +
                                    "_s = Para_s->"+data.getVariable()+";\n");

                        }
                    }
                    if(data.getAttribute().equals("outonly")){
                        if(data.getglbSharedMem()){
                            // global shared variable definition and transfer
                            String datasize = data.getDataSize();
                            if(datasize.contains("*"))
                                datasize = datasize.substring(datasize.indexOf("*")+1);
                            logger.info("datasize: " + datasize);
                            utility.globalDef.add("__thread_local_share volatile " + data.getType() + " " + data.getVariable() +
                                    "_s[" + datasize + "]    __attribute__ ((aligned(64))) = { 0 };\n\n");
                        }
                        else {
                            buftree.append("  " +data.getType() + " *"+ data.getVariable() +
                                    "_s = Para_s->"+data.getVariable()+";\n");
                        }
                    }
                }

                atomCorePartition();
                buftree.append(utility.affineTransOp);
                buftree.append("    bool dataLoad = true;\n\n");
                buftree.append(utility.threadTffineTrans);

            }
            buftree.append(args);

            if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)) {
                //this bracket is closed to threadid for loop
                buftree.append("\n    }\n");
                if(utility.globalScopeDef.getMaxDim().equals(dataPattern.type.THREEDIM)){
                    for(int i = 0; i < dataPatternList.size(); i++){
                        dataPattern obj = dataPatternList.get(i);
                        if(obj.getPattenType().equals(dataPattern.type.THREEDIM)){
                            buftree.append("    stride = (blockId_z *Para_s->cuBlock[2]+Para_s->cuBlock[2]-1)*"+obj.getzDim()+" \n" +
                                    "              + (blockId_y *Para_s->cuBlock[1]+Para_s->cuBlock[1]-1)*" +
                                    obj.getyDim()+" +blockId_x *Para_s->cuBlock[0];\n");
                            buftree.append("    CRTS_dma_iput(&Para_s->" + obj.getVariable() + "[stride], " + obj.getVariable() +
                                    "_s, sizeof(" + obj.getVarType() + ") * Para_s->cuBlock[0], &dma_rply);\n");
                            buftree.append("    D_COUNT++;\n");
                            buftree.append("    CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                        }
                    }
                }

                /*for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                    pointerDataAttr data = utility.pointerDataAttrList.get(i);
                    if(data.getAttribute().equals("inout") || data.getAttribute().equals("outonly")){
                        if(!data.getglbSharedMem()) {
                            // DMA transfer for one block
                            buftree.append("    //todo: user need modify data size of DMA according to the practical situation\n");
                            buftree.append("    CRTS_dma_iput(&Para_s->" + data.getVariable() + "[stride], " + data.getVariable()
                                    + "_s, sizeof(" + data.getType() + ") * threadSum, &dma_rply);\n");
                            buftree.append("    D_COUNT++;\n" + "    CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                        }
                    }
                }*/
                //this bracket is closed to blockid for loop
                buftree.append("\n  }\n");
                //atomic finish operation
                if(directiveDef.isAtomOpr())
                    buftree.append("\n         finish_data_sending(receiveId, &rw_rply[blockIndex]);\n");

                for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                    pointerDataAttr data = utility.pointerDataAttrList.get(i);
                    if(data.getAttribute().equals("readonly") && data.getldmByDma()){
                        buftree.append("    //todo: user need modify data size according to the practical situation\n");
                        buftree.append("\n    " + "ldm_free(" + data.getVariable() + "_s, " +
                                 data.getDataSize() + ");\n");
                    }
                    if(data.getAttribute().equals("inout") || data.getAttribute().equals("outonly")){
                        // global shared variable transfer back
                        if(data.getglbSharedMem()){
                            buftree.append("    athread_ssync_array();\n");
                            buftree.append("    CRTS_memcpy_sldm(" + "Para_s->"+ data.getVariable() +", "+
                                    data.getVariable() + "_s, " + data.getDataSize() + ", LDM_TO_MEM);\n");
                            buftree.append("    CRTS_ssync_sldm();\n\n");

                        }
                    }
                }

                if(directiveDef.isAtomOpr()) {
                    buftree.append("\n    }   \n" +
                            "    else{\n" +
                            "        int offset = (blockIndex-CP_CORE)*dataStride;");
                    buftree.append("\n        receiving_core_get_data(&Para_s->" +atomAttr.getVariable() +
                            "[offset],dmaSize,dataStride);\n" + "    }");
                }

                buftree.append("\n    ldm_free(Para_s, sizeof(Para));");

            }

            setclass(ctx, buftree.toString());
            logger.info("compoundstatement\t\n"+buftree.toString());
        }

        if(ctx.functiontryblock()!=null){
            String args = ctx.functiontryblock().getText();
            logger.info("functiontryblock\t\n"+args);
        }
    }

    @Override
    public void exitCompoundstatement(CPP14Parser.CompoundstatementContext ctx)
    {

        if(ctx.statementseq()!=null){
            String args = getclass(ctx.statementseq());
            setclass(ctx, args);
            logger.info("statementseq0000\t\n" + args);
        }
    }

    @Override
    public void exitStatementseq(CPP14Parser.StatementseqContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.statementseq()!=null){
            String args = getclass(ctx.statementseq());
            buftree.append(args);
            logger.info("statementseq\t\n"+buftree.toString());
        }

        if(ctx.statement()!=null){
            String args = getclass(ctx.statement());
            if(args!=null) {
                buftree.append("      " + args);
                logger.info("statement000000\t\n" + args);
            }
            //add openacc directive from PRAGMA channel
            Token semi = ctx.getStop();
            int i = semi.getTokenIndex();
            List<Token> cmtChannel = Cpptokens.getHiddenTokensToRight(i, CPP14Lexer.PRAGMA);
            if(cmtChannel!=null){
                Token cmt = cmtChannel.get(0);
                if(cmt!=null){
                    logger.info("getHiddenTokensToRightPRAGMAstatement\t\n" + cmt.getText());
                    buftree.append("\t" + cmt.getText()+"\t\n");
                }
            }

            logger.info("getHiddenTokensToRightINCLUD getTokenIndex: " + i+
                    " getStartIndex: "+ semi.getStartIndex());
            List<Token> includeChannel = Cpptokens.getHiddenTokensToRight(i, CPP14Lexer.INCLUDE);
            if(includeChannel!=null){
                for(int j=0; j<includeChannel.size();j++){
                    Token cmt = includeChannel.get(j);
                    buftree.append("\t" + cmt.getText()+"\t\n");
                    logger.info("getHiddenTokensToRightINCLUDEstatement\t\n" + cmt.getText());
                }
            }
        }

        if(utility.globalScopeDef.getDmaStride()  && dmaTrans
                && utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)){
            //add slice dma transfer code according to the max dimensions
            boolean addOnce = false;
            boolean mixTwoThree = false;
            boolean threeOnly = false;
            boolean twoOnly = false;
            StringBuilder twoDimDMA  = new StringBuilder();
            StringBuilder twoDimDMA1  = new StringBuilder();
            StringBuilder twoDimDMA2  = new StringBuilder();
            buftree.append("\n      if((threadId != 0) && (threadId_x == 0)){\n");

            for (int i = 0; i < dataPatternList.size(); i++){
                dataPattern temp = dataPatternList.get(i);
                if(temp.getPattenType().equals(dataPattern.type.TWODIM) && utility.globalScopeDef.getMaxDim().equals(dataPattern.type.THREEDIM))
                    mixTwoThree = true;
            }

            if(utility.globalScopeDef.getMaxDim().equals(dataPattern.type.THREEDIM)){
                if(!mixTwoThree)
                    threeOnly = true;
                buftree.append("        if(threadId_y !=0 ) {\n");
                if(mixTwoThree) {
                    twoDimDMA.append("          if(k == 0) {\n");
                    twoDimDMA1.append("          if(k == 1) {\n");
                    twoDimDMA2.append("        if(k == 0) {\n");
                }

                for (int i = 0; i < dataPatternList.size(); i++) {
                    dataPattern temp = dataPatternList.get(i);
                    if(temp.getPattenType().equals(dataPattern.type.THREEDIM)){
                        // k*imt*jmt + (j-1)*imt + i
                        String usage = temp.getzInd() + "*" + temp.getzDim() + "+(" + temp.getyInd() +
                                "-1)*" + temp.getyDim() + "+"+temp.getxInd();
                        buftree.append("          CRTS_dma_iput(&Para_s->" + temp.getVariable() + "["+
                                usage + "], " + temp.getVariable() + "_s, sizeof(" + temp.getVarType()
                                + ")*Para_s->cuBlock[0], &dma_rply);\n");
                        buftree.append("          D_COUNT++;\n" +
                                "          CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }

                    if(temp.getPattenType().equals(dataPattern.type.TWODIM)){
                        String usage = "(" + temp.getyInd() +
                                "-1)*" + temp.getyDim() + "+"+temp.getxInd();
                        twoDimDMA.append("            CRTS_dma_iput(&Para_s->" + temp.getVariable() + "["+
                                usage + "], " + temp.getVariable() + "_s, sizeof(" + temp.getVarType()
                                + ")*Para_s->cuBlock[0], &dma_rply);\n");
                        twoDimDMA.append("            D_COUNT++;\n" +
                                "            CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }

                    logger.info("dataPatternList111 " + i + " patten1: " + temp.getPattern1() + " pattern2: " + temp.getPattern2()
                            + " pattern3: " + temp.getPattern3() + " var: " + temp.getVariable() + " type: " +temp.getVarType() + " usage: "
                            + temp.getDataUsage() + " dimType: " + temp.getPattenType() + " yDim: " + temp.getyDim());

                } //dataPatternList loop
                if(mixTwoThree) {
                    twoDimDMA.append("          }\n");
                    buftree.append(twoDimDMA);
                }
                buftree.append("        }\n" +
                        "        else{\n");
                for (int i = 0; i < dataPatternList.size(); i++) {
                    dataPattern temp = dataPatternList.get(i);
                    if(temp.getPattenType().equals(dataPattern.type.THREEDIM)) {
                        //(k-1)*jmt *imt
                        String usage = "(" + temp.getzInd() + "-1)*" + temp.getzDim();
                        buftree.append("          stride = " + usage +
                                " + (blockId_y *Para_s->cuBlock[1]+Para_s->cuBlock[1]-1)*"+
                                temp.getyDim()+" +blockId_x *Para_s->cuBlock[0];\n");
                        buftree.append("          CRTS_dma_iput(&Para_s->"+ temp.getVariable() + "[stride], " +
                                temp.getVariable() + "_s, sizeof(" + temp.getVarType()
                                +")*Para_s->cuBlock[0], &dma_rply);\n");
                        buftree.append("          D_COUNT++;\n" +
                                "          CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }

                    if(temp.getPattenType().equals(dataPattern.type.TWODIM)){
                        twoDimDMA1.append("            stride = (blockId_y *Para_s->cuBlock[1]+Para_s->cuBlock[1]-1)*"+
                                temp.getyDim()+" +blockId_x *Para_s->cuBlock[0];\n");
                        twoDimDMA1.append("            CRTS_dma_iput(&Para_s->" + temp.getVariable() + "[stride], " +
                                 temp.getVariable() + "_s, sizeof("+ temp.getVarType() + ")*Para_s->cuBlock[0], &dma_rply);\n");
                        twoDimDMA1.append("            D_COUNT++;\n" +
                                "            CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }
                }//dataPatternList loop
                if(mixTwoThree) {
                    twoDimDMA1.append("          }\n");
                    buftree.append(twoDimDMA1);
                }

                buftree.append("        }\n" +
                        "        dataLoad = true;\n" +
                        "      }    \n" +
                        "      if(dataLoad){\n");

                for (int i = 0; i < dataPatternList.size(); i++) {
                    dataPattern temp = dataPatternList.get(i);
                    if(temp.getPattenType().equals(dataPattern.type.THREEDIM)) {
                        String usage = temp.getDataUsage();
                        buftree.append("        CRTS_dma_iget(" + temp.getVariable() + "_s, &Para_s->"+
                                temp.getVariable() + "[" + usage + "], sizeof("+temp.getVarType()
                                +") * Para_s->cuBlock[0], &dma_rply);\n");
                        buftree.append("        D_COUNT++;\n" +
                                "        CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }
                    if(temp.getPattenType().equals(dataPattern.type.TWODIM)){
                        String usage = temp.getDataUsage();
                        twoDimDMA2.append("          CRTS_dma_iget(" + temp.getVariable() + "_s, &Para_s->"+
                                temp.getVariable() + "[" + usage + "], sizeof("+ temp.getVarType()
                                + ") * Para_s->cuBlock[0], &dma_rply);\n");
                        twoDimDMA2.append("          D_COUNT++;\n" +
                                "          CRTS_dma_wait_value(&dma_rply, D_COUNT);\n\n");
                    }
                }//dataPatternList loop
                if(mixTwoThree) {
                    twoDimDMA2.append("        }\n");
                    buftree.append(twoDimDMA2);
                }
                buftree.append("        dataLoad = false;\n" +
                        "      }\n\n");

            }//max three dimension

            dmaTrans = false;

        }
        setclass(ctx, buftree.toString());
        logger.info("statementseq final\t\n"+ buftree.toString());
    }

    @Override
    public void exitStatement(CPP14Parser.StatementContext ctx)
    {
        if(ctx.labeledstatement()!=null){
            String args = ctx.labeledstatement().getText();
            logger.info("labeledstatement\t\n"+args);
        }
        if(ctx.expressionstatement()!=null){
            String args = getclass(ctx.expressionstatement());
            StringBuilder buftree = new StringBuilder();
            buftree.append(args+";\t\n");
            setclass(ctx, buftree.toString());
            logger.info("expressionstatement\t\n"+getclass(ctx.expressionstatement()));
        }
        if(ctx.attributespecifierseq()!=null){
            String args = ctx.attributespecifierseq().getText();
            logger.info("attributespecifierseq\t\n"+args);
        }
        if(ctx.compoundstatement()!=null){
            String args = getclass(ctx.attributespecifierseq());
            logger.info("compoundstatement000\t\n"+args);
        }
        if(ctx.selectionstatement()!=null){
            String args = getclass(ctx.selectionstatement());
            setclass(ctx, args);
            logger.info("selectionstatement\t\n"+args);
        }
        if(ctx.iterationstatement()!=null){
            String args = getclass(ctx.iterationstatement());
            setclass(ctx, args);
            logger.info("iterationstatement\t\n"+args);
        }
        if(ctx.jumpstatement()!=null){
            String args = getclass(ctx.jumpstatement());
            setclass(ctx, args);
            logger.info("jumpstatement\t\n"+args);
        }
        if(getclass(ctx.declarationstatement())!=null){
            StringBuilder buftree = new StringBuilder(getclass(ctx.declarationstatement()));
            buftree.append("\t\n");
            setclass(ctx, buftree.toString());
            logger.info("declarationstatement\t\n" + getclass(ctx.declarationstatement()));
        }
        if(ctx.tryblock()!=null){
            String args = getclass(ctx.tryblock());
            logger.info("tryblock\t\n"+args);
        }
        if(ctx.Noncontenctbrace()!=null){
            String args = ctx.Noncontenctbrace().getText();
            setclass(ctx, args);
            logger.info("Noncontenctbrace\t\n"+args);
        }
    }

    @Override public void exitTryblock(CPP14Parser.TryblockContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Try()!=null)
            buftree.append(ctx.Try().getText());

        if(ctx.compoundstatement()!=null){
            String args = getclass(ctx.compoundstatement());
            buftree.append("{\n" + args + "\n\t}");
        }

        if(ctx.handlerseq()!=null){
            String args = getclass(ctx.handlerseq());
            buftree.append(args);
            logger.info("exitTryblock handlerseq\t\n"+args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitTryblock final\t\n"+getclass(ctx));

    }

    @Override
    public void exitHandlerseq(CPP14Parser.HandlerseqContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.handler()!=null) {
            String args = getclass(ctx.handler());
            buftree.append(args);
        }

        if(ctx.handlerseq()!=null){
            String args = getclass(ctx.handlerseq());
            buftree.append(args);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitHandlerseq final\t\n"+getclass(ctx));
    }

    @Override
    public void exitHandler(CPP14Parser.HandlerContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Catch()!=null)
            buftree.append(ctx.Catch().getText());
        if(ctx.LeftParen()!=null)
            buftree.append(ctx.LeftParen().getText());
        if(ctx.exceptiondeclaration()!=null){
            String args = getclass(ctx.exceptiondeclaration());
            buftree.append(args);
        }
        if(ctx.RightParen()!=null)
            buftree.append(ctx.RightParen().getText());

        if(ctx.compoundstatement()!=null){
            String args = getclass(ctx.compoundstatement());
            buftree.append("{\n" + args + "\n\t}");
        }

        setclass(ctx, buftree.toString());
        logger.info("exitHandler final\t\n"+getclass(ctx));

    }

    @Override
    public void exitExceptiondeclaration(CPP14Parser.ExceptiondeclarationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.typespecifierseq()!=null){
            String args = getclass(ctx.typespecifierseq());
            buftree.append(args + " ");
        }
        if(ctx.declarator()!=null){
            String args = getclass(ctx.declarator());
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitExceptiondeclaration final\t\n"+getclass(ctx));
    }

    @Override
    public void exitThetypeid(CPP14Parser.ThetypeidContext ctx) {
        if (ctx.typespecifierseq() != null) {
            String args = getclass(ctx.typespecifierseq());
            setclass(ctx, args);
            logger.info("typespecifierseqsec" + args);
        }
    }

    @Override
    public void exitTypespecifierseq(CPP14Parser.TypespecifierseqContext ctx) {
        if (ctx.typespecifierseq() != null) {
            String args = getclass(ctx.typespecifierseq());
            setclass(ctx, args);
            logger.info("typespecifierseq\t\n" + args);
        }

        if (ctx.typespecifier() != null) {
            String args = getclass(ctx.typespecifier());
            setclass(ctx, args);
            logger.info("exitTypespecifierseq final\t\n" + args);
        }
    }

    @Override
    public void exitJumpstatement(CPP14Parser.JumpstatementContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Break()!=null){
            String args = ctx.Break().getText();
            buftree.append(args+" ");
            logger.info("Jumpstatement Break\t\n"+args);
        }
        if(ctx.Continue()!=null){
            String args = ctx.Continue().getText();
            buftree.append(args+" ");
            logger.info("Jumpstatement Continue\t\n"+args);
        }
        if(ctx.Return()!=null){
            String args = ctx.Return().getText();
            buftree.append(args +" ");
            logger.info("Jumpstatement Return\t\n"+args);
        }
        if(ctx.expression()!=null){
            String args = getclass(ctx.expression());
            buftree.append(args);
            logger.info("Jumpstatement expression\t\n"+args);
        }

        if(ctx.bracedinitlist()!=null){
            String args = ctx.bracedinitlist().getText();
            buftree.append(args);
            logger.info("Jumpstatement bracedinitlist\t\n"+args);
        }

        if(ctx.Goto()!=null){
            String args = ctx.Goto().getText();
            buftree.append(args+" ");
            logger.info("Jumpstatement Goto\t\n"+args);
        }
        if(ctx.Identifier()!=null){
            String args = ctx.Identifier().getText();
            buftree.append(args);
            logger.info("Jumpstatement Identifier\t\n"+args);
        }

        buftree.append(";\t\n");
        // cuda global kernel entry, ignore return
        if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)&&buftree.toString().contains("return"))
            logger.info("ignore return in kernel entry function\n"  + getclass(ctx));
        else
            setclass(ctx, buftree.toString());
        logger.info("exitJumpstatement final\t\n"+getclass(ctx) + " scope:" + utility.globalScopeDef.getScope());
    }

    @Override
    public void exitIterationstatement(CPP14Parser.IterationstatementContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.For()!=null)
            buftree.append(ctx.For().getText()+"(");

        if(ctx.While()!=null)
            buftree.append(ctx.While().getText()+"(");

        if(ctx.forinitstatement()!=null) {
            String args = getclass(ctx.forinitstatement());
            buftree.append(args);
            logger.info("forinitstatement\t\n" + args);
        }
        if(ctx.condition()!=null) {
            String args = ctx.condition().getText();
            if(ctx.For()!=null)
                buftree.append(args+"; ");
            else if(ctx.While()!=null)
                buftree.append(args+")");
            logger.info("condition\t\n" + args);
        }
        if(ctx.expression()!=null) {
            String args = getclass(ctx.expression());
            buftree.append(args+")\t\n");
            logger.info("expression\t\n" + args);
        }

        if(ctx.forrangedeclaration()!=null){
            String args = getclass(ctx.forrangedeclaration());
            buftree.append(args);
        }
        if(ctx.Colon()!=null)
            buftree.append(ctx.Colon());
        if(ctx.forrangeinitializer()!=null){
            String args = getclass(ctx.forrangeinitializer());
            buftree.append(args+")");
        }

        if(ctx.statement()!=null) {
            String args = getclass(ctx.statement());
            String args1 = getclass(ctx.statement().compoundstatement());
            if(args1!=null)
                buftree.append("\t{\t\n"+args1+"\t}\t\n");
            else
                buftree.append(args+"\t\n");
            logger.info("statementseqIterationstatement\t\n" + args1);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitIterationstatement\t\n" + getclass(ctx));
    }

    @Override
    public void exitForrangedeclaration(CPP14Parser.ForrangedeclarationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.declspecifierseq()!=null){
            String args = getclass(ctx.declspecifierseq());
            buftree.append(args+" ");
        }
        if(ctx.declarator()!=null){
            String args = getclass(ctx.declarator());
            buftree.append(args);
        }
        setclass(ctx,buftree.toString());
        logger.info("exitForrangedeclaration final\t\n" + getclass(ctx));
    }

    @Override
    public void exitForrangeinitializer(CPP14Parser.ForrangeinitializerContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.expression()!=null){
            String args = getclass(ctx.expression());
            buftree.append(args);
        }

        if(ctx.bracedinitlist()!=null){
            String args = getclass(ctx.bracedinitlist());
            buftree.append(args);
        }

        setclass(ctx,buftree.toString());
        logger.info("exitForrangeinitializer final\t\n" + getclass(ctx));
    }

    @Override
    public void exitForinitstatement(CPP14Parser.ForinitstatementContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.expressionstatement()!=null) {
            String args = getclass(ctx.expressionstatement());
            if(args!=null)
                buftree.append(args+";");
            else
                buftree.append(";");
            setclass(ctx, buftree.toString());
            logger.info("exitForinitstatement expressionstatement\t\n" + args);
        }

        if(ctx.simpledeclaration()!=null) {
            String args = getclass(ctx.simpledeclaration());
            //buftree.append(args+")\t\n");
            setclass(ctx, args);
            logger.info("exitForinitstatement simpledeclaration\t\n" + args);
        }
    }

    @Override
    public void exitCondition(CPP14Parser.ConditionContext ctx)
    {
        StringBuilder bufree = new StringBuilder();
        if(ctx.expression()!=null){
            String args = getclass(ctx.expression());
            logger.info("exitCondition expressionsec" + args);
            setclass(ctx, args);
        }
        if(ctx.declspecifierseq()!=null){
            String args = getclass(ctx.declspecifierseq());
            bufree.append(bufree);
            logger.info("exitCondition declspecifierseqsec" + args);
        }
        if(ctx.declarator()!=null){
            String args = getclass(ctx.declarator());
            bufree.append(args);
            logger.info("exitCondition declaratorsec" + args);
        }
        if(ctx.Assign()!=null)
            bufree.append(ctx.Assign().getText());

        if(ctx.initializerclause()!=null){
            String args = getclass(ctx.initializerclause());
            bufree.append(args);
            setclass(ctx, bufree.toString());
            logger.info("exitCondition initializerclausesec" + bufree.toString());
        }

        if (ctx.bracedinitlist() != null) {
            String args = getclass(ctx.bracedinitlist());
            bufree.append(args);
            setclass(ctx, bufree.toString());
            logger.info("exitCondition bracedinitlistsec" + bufree.toString());
        }
    }


    @Override
    public void exitSelectionstatement(CPP14Parser.SelectionstatementContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.If()!=null)
            buftree.append(ctx.If().getText()+"(");
        if(ctx.Switch()!=null)
            buftree.append(ctx.Switch().getText()+"(");

        if(ctx.condition()!=null) {
            String args = getclass(ctx.condition());
            buftree.append(args+")\t\n");
            logger.info("condition\t\n" + args);
        }

        if(ctx.statement(0)!=null) {
            String args = getclass(ctx.statement(0));
            String args1 = getclass(ctx.statement(0).compoundstatement());
            //for  selection statement, first to find if it has compundstatement.
            if(args1!=null)
                buftree.append("      {\t\n"+args1+"      }\t\n");
            else{
                /* the "else if" should be in the same line
                 * else
                 * 		if(b==NULL)		{
                 *lastPtrRef=a;	}
                 */
                if (ctx.Else() != null)
                    buftree.append(args + "\t\n");
                else
                    buftree.append("\n\t\t" + args + "\t\n");
            }

            logger.info("statement0\t\n" + args);
            logger.info("if-statement-compoundstatement\t\n" + args1);
        }
        if(ctx.Else()!=null)
            buftree.append("      "+ctx.Else().getText()+"\t");

        if(ctx.statement(1)!=null) {
            String args = getclass(ctx.statement(1));
            String args1 = getclass(ctx.statement(1).compoundstatement());
            if(args1!=null)
                buftree.append("{\n\t"+args1+"      }\t\n");
            else
                buftree.append("\n      "+args+"\t\n");
            logger.info("statement1\t\n" + args);
            logger.info("else-statement-compoundstatement\t\n" + args1);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitSelectionstatement\t\n" + getclass(ctx));
    }

    @Override
    public void exitDeclarationstatement(CPP14Parser.DeclarationstatementContext ctx)
    {

        if(getclass(ctx.blockdeclaration())!=null){
            String args = getclass(ctx.blockdeclaration());
            //save the functionname, variable, type
            String variable=null;
            String type=null;
            String temp = null;
            if(args.contains("=")) {
                // for example: unsigned 	int array_size=this->array_size;
                temp = args.substring(0, args.indexOf("="));
            }
            else {
                //for example: std::chrono::high_resolution_clock::time_point t1,t2;
                temp = args.substring(0, args.indexOf(";"));
            }
            if(temp.contains(" ")) {
                if(temp.contains("(")){
                    // for example: ifile in(p );
                    int index = 0;
                    String subtemp = temp.substring(0, temp.indexOf("("));
                    if(temp.substring(0, temp.indexOf("(")).contains(" "))
                        index = subtemp.lastIndexOf(" ");
                    variable = temp.substring(index).trim();
                    type = temp.substring(0, index).trim();
                }
                else {
                    variable = temp.substring(temp.lastIndexOf(" ") + 1);
                    type = temp.substring(0, temp.lastIndexOf(" "));
                }
            }

            setclass(ctx, args);
            logger.info("blockdeclaration111\t\n" + args);
        }
    }

    @Override
    public void exitExpressionstatement(CPP14Parser.ExpressionstatementContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.expression()!=null){
            String args = getclass(ctx.expression());
            buftree.append("\t" + args);
            setclass(ctx, buftree.toString());
            logger.info("expression111\t\n"+buftree.toString());
        }
    }

    @Override
    public void exitExpression(CPP14Parser.ExpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if (ctx.expression() != null) {
            String args = getclass(ctx.expression());
            buftree.append(args+",");
            logger.info("expressionsec\t\n" + args);
        }

        if (ctx.assignmentexpression() != null) {
            String args = getclass(ctx.assignmentexpression());
            buftree.append(args);

            logger.info("assignmentexpression\t\n" + args);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitExpression final \t\n" + buftree.toString());
    }

    @Override
    public void exitAssignmentexpression(CPP14Parser.AssignmentexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        String index = null;
        if(ctx.conditionalexpression()!=null){
            String args = getclass(ctx.conditionalexpression());
            setclass(ctx, args);
            logger.info("conditionalexpression\t\n"+args);
        }

        if(ctx.logicalorexpression()!=null){
            String args = getclass(ctx.logicalorexpression());
            index = args;
            buftree.append(args);
            logger.info("logicalorexpression2222\t\n"+getclass(ctx.logicalorexpression()));
        }

        if(ctx.assignmentoperator()!=null){
            String args = ctx.assignmentoperator().getText();
            buftree.append(args);
            logger.info("assignmentoperator\t\n"+args);
        }

        if(ctx.initializerclause()!=null){
            String args = getclass(ctx.initializerclause());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("initializerclause222\t\n"+getclass(ctx));
            String tmp = getclass(ctx.initializerclause());
            if(tmp.contains("blockId_x *Para_s->cuBlock[0]")) {
                utility.globalScopeDef.setxInd(index);
                if(utility.globalScopeDef.getMaxDim().equals(dataPattern.type.ONEDIM))
                    dmaTrans = true;
            }
            if(tmp.contains("blockId_y *Para_s->cuBlock[1]")) {
                utility.globalScopeDef.setyInd(index);
                if(utility.globalScopeDef.getMaxDim().equals(dataPattern.type.TWODIM))
                    dmaTrans = true;
            }
            if(tmp.contains("blockId_z *Para_s->cuBlock[2]")) {
                utility.globalScopeDef.setyInd(index);
                if(utility.globalScopeDef.getMaxDim().equals(dataPattern.type.THREEDIM))
                    dmaTrans = true;
            }
            logger.info("initializerclause333: "+getclass(ctx.initializerclause()) + " index: " + index);
        }

        if(ctx.throwexpression()!=null){
            String args = ctx.throwexpression().getText();
            logger.info("throwexpression\t\n"+args);
        }
    }

    @Override
    public void exitInitializerclause(CPP14Parser.InitializerclauseContext ctx)
    {
        if(ctx.assignmentexpression()!=null){
            String args = getclass(ctx.assignmentexpression());
            setclass(ctx, args);
            logger.info("assignmentexpression000\t\n"+args);
        }

        if(ctx.bracedinitlist()!=null){
            String args = getclass(ctx.bracedinitlist());
            //setclass(ctx, getclass(ctx.bracedinitlist()));
            logger.info("bracedinitlist\t\n"+args);
        }
    }

    @Override
    public void exitConditionalexpression(CPP14Parser.ConditionalexpressionContext ctx)
    {
        if(ctx.logicalorexpression()!=null){
            String args = getclass(ctx.logicalorexpression());
            setclass(ctx,args);
            logger.info("logicalorexpression1111\t\n"+getclass(ctx.logicalorexpression()));
        }

        if(ctx.expression()!=null){
            String args = getclass(ctx.expression());
            logger.info("expression\t\n"+args);
        }

        if(ctx.assignmentexpression()!=null){
            String args = getclass(ctx.assignmentexpression());
            logger.info("assignmentexpression\t\n"+args);
        }

    }

    @Override
    public void exitLogicalorexpression(CPP14Parser.LogicalorexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if (ctx.logicalorexpression() != null) {
            String args = getclass(ctx.logicalorexpression());
            buftree.append(args);
            logger.info("logicalorexpression0000sec\t\n" + args);
        }
        if(ctx.oroperator()!=null)
            buftree.append("||");
        if (ctx.logicalandexpression() != null) {
            String args = getclass(ctx.logicalandexpression());
            buftree.append(args);
            logger.info("logicalandexpression000sec\t\n" + args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitLogicalorexpression final\t\n" + buftree.toString());

    }

    @Override
    public void exitLogicalandexpression(CPP14Parser.LogicalandexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if (ctx.logicalandexpression() != null) {
            String args = getclass(ctx.logicalandexpression());
            buftree.append(args);
            logger.info("logicalandexpression000\t\n" + args);
        }
        if(ctx.andoperator()!=null)
            buftree.append("&&");
        if (ctx.inclusiveorexpression() != null) {
            String args = getclass(ctx.inclusiveorexpression());
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitLogicalandexpression final\t\n" + buftree.toString());

    }

    @Override
    public void exitInclusiveorexpression(CPP14Parser.InclusiveorexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.inclusiveorexpression()!=null){
            String args = getclass(ctx.inclusiveorexpression());
            buftree.append(args);
            logger.info("inclusiveorexpression000\t\n"+args);
        }

        if(ctx.Or()!=null)
            buftree.append(ctx.Or().getText());

        if(ctx.exclusiveorexpression()!=null){
            String args = getclass(ctx.exclusiveorexpression());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("exclusiveorexpression\t\n"+getclass(ctx.exclusiveorexpression()));
        }

    }

    @Override
    public void exitExclusiveorexpression(CPP14Parser.ExclusiveorexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.exclusiveorexpression()!=null){
            String args = getclass(ctx.exclusiveorexpression());
            buftree.append(args);
            logger.info("exclusiveorexpression000\t\n"+args);
        }
        if(ctx.Caret()!=null)
            buftree.append(ctx.Caret().getText());

        if(ctx.andexpression()!=null){
            String args = getclass(ctx.andexpression());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("andexpression\t\n"+getclass(ctx.andexpression()));
        }


    }

    @Override
    public void exitAndexpression(CPP14Parser.AndexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.andexpression()!=null){
            String args = getclass(ctx.andexpression());
            buftree.append(args);
            logger.info("andexpression000\t\n"+args);
        }

        if(ctx.And()!=null)
            buftree.append(ctx.And().getText());

        if(ctx.equalityexpression()!=null){
            String args = getclass(ctx.equalityexpression());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("equalityexpression\t\n"+getclass(ctx.equalityexpression()));
        }

    }

    @Override
    public void exitEqualityexpression(CPP14Parser.EqualityexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.equalityexpression()!=null){
            String args = getclass(ctx.equalityexpression());
            buftree.append(args);
            logger.info("equalityexpression000\t\n"+args);
        }
        if(ctx.Equal() != null)
            buftree.append(ctx.Equal().getText());

        if(ctx.NotEqual()!=null)
            buftree.append(ctx.NotEqual().getText());

        if(ctx.relationalexpression()!=null){
            String args = getclass(ctx.relationalexpression());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("relationalexpression\t\n"+getclass(ctx.relationalexpression()));
        }


    }

    @Override
    public void exitRelationalexpression(CPP14Parser.RelationalexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if (ctx.relationalexpression() != null) {
            String args = getclass(ctx.relationalexpression());
            buftree.append(args);
            logger.info("relationalexpression000\t\n" + args);
        }

		/*if (ctx.Less() != null) {
			buftree.append(ctx.Less().getText());
		}*/

        if (ctx.Greater() != null) {
            buftree.append(ctx.Greater().getText()+" ");
        }

        if (ctx.LessEqual() != null) {
            buftree.append(ctx.LessEqual().getText());
        }
        if (ctx.GreaterEqual() != null) {
            buftree.append(ctx.GreaterEqual().getText());
        }

        if (ctx.shiftexpression() != null) {
            String args = getclass(ctx.shiftexpression());
            buftree.append(args);
            // setclass(ctx,args);
            logger.info("shiftexpression\t\n" + getclass(ctx.shiftexpression()));
        }

        setclass(ctx, buftree.toString());
        logger.info("relationalexpressionfinal \t\n" + getclass(ctx));
    }

    @Override
    public void exitShiftexpression(CPP14Parser.ShiftexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.shiftexpression()!=null){
            String args = getclass(ctx.shiftexpression());
            buftree.append(args);
            logger.info("shiftexpression000\t\n"+args);
        }

        if(ctx.shiftoperator()!=null){
            String args = ctx.shiftoperator().getText();
            buftree.append(args);
            logger.info("shiftoperator\t\n"+args);
        }
        if (ctx.Less() != null) {
            buftree.append(ctx.Less().getText());
        }

        if(ctx.additiveexpression()!=null){
            String args = getclass(ctx.additiveexpression());
            buftree.append(args);
            logger.info("additiveexpression\t\n"+getclass(ctx.additiveexpression()));
        }
        setclass(ctx,buftree.toString());
        logger.info("shiftexpression000 final\t\n"+getclass(ctx));

    }

    @Override
    public void exitAdditiveexpression(CPP14Parser.AdditiveexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.additiveexpression()!=null){
            String args = getclass(ctx.additiveexpression());
            buftree.append(args);
            logger.info("additiveexpression000\t\n"+args);
        }

        if(ctx.Plus()!=null){
            String args = ctx.Plus().getText();
            buftree.append("+");
            logger.info("additiveexpression000 plus\t\n"+args);
        }

        if(ctx.Minus()!=null){
            String args = ctx.Minus().getText();
            buftree.append("-");
            logger.info("additiveexpression000 Minus\t\n"+args);
        }

        if(ctx.multiplicativeexpression()!=null){
            String args = getclass(ctx.multiplicativeexpression());
            buftree.append(args);
            logger.info("multiplicativeexpression222\t\n"+args);
        }

        setclass(ctx,buftree.toString());

        logger.info("exitAdditiveexpression final \t\n"+buftree.toString());


    }

    @Override
    public void exitMultiplicativeexpression(CPP14Parser.MultiplicativeexpressionContext ctx)
    {
        String symbol=null;
        StringBuilder builder = new StringBuilder();

        if(ctx.multiplicativeexpression()!=null){
            String args = getclass(ctx.multiplicativeexpression());
            builder.append(args+" ");
            logger.info("multiplicativeexpression000\t\n"+args);
        }

        if(ctx.Star()!=null)
            symbol=ctx.Star().getText();
        else if(ctx.Div()!=null)
            symbol=ctx.Div().getText();
        else if(ctx.Mod()!=null)
            symbol=ctx.Mod().getText();
        //logger.info("multiplicativeexpression000+symbol\t\n"+symbol);
        if(symbol!=null)
            builder.append(symbol);

        if(ctx.restrictoperator()!=null){
            String args = ctx.pmexpression().getText();
            //setclass(ctx, args);
            logger.info("restrictoperator\t\n"+args);
            //builder.append(args);
        }


        if(ctx.pmexpression()!=null){
            String args = getclass(ctx.pmexpression());
            //setclass(ctx, args);
            logger.info("pmexpression\t\n"+args);
            builder.append(args);
        }

        setclass(ctx, builder.toString());
        logger.info("multiplicativeexpression111\t\n"+getclass(ctx));
    }

    @Override
    public void exitPmexpression(CPP14Parser.PmexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if (ctx.pmexpression() != null) {
            String args = getclass(ctx.pmexpression());
            buftree.append(args);
            logger.info("pmexpression000\t\n" + args);
        }

        if(ctx.DotStar()!=null)
            buftree.append(ctx.DotStar().getText());
        if(ctx.ArrowStar()!=null)
            buftree.append(ctx.ArrowStar().getText());

        if (ctx.castexpression() != null) {
            String args = getclass(ctx.castexpression());
            buftree.append(args);
            setclass(ctx, buftree.toString());
            logger.info("exitPmexpression final\t\n" + buftree.toString());
        }


    }

    @Override
    public void exitCastexpression(CPP14Parser.CastexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.unaryexpression()!=null){
            String args = getclass(ctx.unaryexpression());
            setclass(ctx,args);
            logger.info("unaryexpression\t\n"+args);
        }

        if(ctx.thetypeid()!=null){
            String args = getclass(ctx.thetypeid());
            buftree.append("("+args+")");
            logger.info("thetypeid\t\n"+args);
        }

        if(ctx.castexpression()!=null){
            String args = getclass(ctx.castexpression());
            buftree.append(args);
            setclass(ctx,buftree.toString());
            logger.info("castexpression111sec\t\n"+getclass(ctx));
        }
    }

    @Override
    public void exitUnaryexpression(CPP14Parser.UnaryexpressionContext ctx) {
        StringBuilder buf = new StringBuilder();
        if (ctx.postfixexpression() != null) {
            StringBuilder buffer = new StringBuilder();
            String args = getclass(ctx.postfixexpression());
            //core atomic translation
            if(directiveDef.isAtomOpr()){
                //todo: here only handle atomic add operation, other atomic operation needed to do in the following
                if(args.contains("atomicAdd")){
                    String offset = null;
                    String tmpStr = args.substring(args.indexOf("(")+1,args.lastIndexOf(")"));
                    String leftExp = tmpStr.substring(0, tmpStr.lastIndexOf(","));
                    String val = tmpStr.substring(tmpStr.lastIndexOf(",")+1);
                    logger.info("exitUnaryexpression atomic expression: " + tmpStr + " val:" + val);
                    if(leftExp.contains("["))
                        offset = leftExp.substring(leftExp.indexOf("[")+1,leftExp.lastIndexOf("]"));
                    else if(leftExp.contains("+"))
                        offset = leftExp.substring(leftExp.lastIndexOf("+")+1);
                    else
                        offset = String.valueOf(0);

                    buffer.append("\n        int offset = " + offset + ";");
                    buffer.append("\n        receiveId = offset / dataStride;");
                    buffer.append("\n        " + atomAttr.getVariable()+ "Val[receiveId][arrayInd[receiveId]*2 + 0] = " +
                            val + ";");
                    buffer.append("\n        " + atomAttr.getVariable()+ "Val[receiveId][arrayInd[receiveId]*2 + 1] = offset;");
                    buffer.append("\n        arrayInd[receiveId]++;");
                    buffer.append("\n        if(arrayInd[receiveId] == DATAPAKAGE) {");
                    buffer.append("\n            send_data_to_rcv_core(receiveId, sizeof(" + atomAttr.getType() + ") * DATAPAKAGE * 2," +
                            "\n                    "+atomAttr.getVariable() + "Val[receiveId], remoteVal[blockIndex], &rw_rply[blockIndex]);");
                    buffer.append("\n            arrayInd[receiveId] = 0;");
                    buffer.append("\n            memset(" + atomAttr.getVariable() + "Val[receiveId], 0, sizeof(" +
                            atomAttr.getType() + ")*DATAPAKAGE*2);");
                    buffer.append("\n        }");
                    setclass(ctx,buffer.toString());
                    logger.info("exitUnaryexpression atomic translation: " + buffer.toString());
                }
                else
                    setclass(ctx, args);
            }
            else {
                setclass(ctx, args);
                logger.info("exitUnaryexpression postfixexpression: " + args);
            }
        }
        if(ctx.PlusPlus()!=null){
            buf.append(ctx.PlusPlus().getText());
        }
        if(ctx.MinusMinus()!=null)
            buf.append(ctx.MinusMinus().getText());

        if (ctx.unaryoperator() != null) {
            String args = ctx.unaryoperator().getText();
            buf.append(args);
            logger.info("unaryoperator: " + args);
        }

        if (ctx.castexpression() != null) {
            String args = getclass(ctx.castexpression());
            buf.append(args);
            setclass(ctx, buf.toString());
            logger.info("exitUnaryexpression castexpression000: " + args);
        }

        if(ctx.Sizeof()!=null)
            buf.append(ctx.Sizeof().getText());

        if(ctx.Alignof()!=null)
            buf.append(ctx.Alignof().getText());

        if(ctx.Ellipsis()!=null)
            buf.append(ctx.Ellipsis().getText());

        if(ctx.LeftParen()!=null)
            buf.append(ctx.LeftParen().getText());

        if(ctx.Identifier()!=null)
            buf.append(ctx.Identifier().getText());

        if(ctx.thetypeid()!=null){
            String args = getclass(ctx.thetypeid());
            logger.info("exitUnaryexpression thetypeidsec: " + args);
            buf.append(args);
        }
        if(ctx.RightParen()!=null) {
            buf.append(ctx.RightParen().getText());
            logger.info("exitUnaryexpression111sec: " + buf.toString());
            setclass(ctx,buf.toString());
        }

        if(ctx.unaryexpression()!=null){
            String args =  getclass(ctx.unaryexpression());
            buf.append(args);
            logger.info("exitUnaryexpression unaryexpression0000: " + buf.toString());
            setclass(ctx,buf.toString());
        }

        if(ctx.noexceptexpression()!=null){
            String args = ctx.noexceptexpression().getText();
            logger.info("exitUnaryexpression noexceptexpression: " + args);
            setclass(ctx,args);
        }

        if (ctx.newexpression() != null) {
            //for example: new forceVecType[nAtom]. the type is template, need to instance
            String args = getclass(ctx.newexpression());
            setclass(ctx, args);
            logger.info("exitUnaryexpression newexpressionsec: " + getclass(ctx));
        }

        if(ctx.deleteexpression()!=null){
            String args = getclass(ctx.deleteexpression());
            logger.info("exitUnaryexpression deleteexpression: " + args);
            setclass(ctx,args);
        }
    }


    @Override
    public void exitDeleteexpression(CPP14Parser.DeleteexpressionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Delete()!=null)
            buftree.append(ctx.Delete().getText());

        if(ctx.castexpression()!=null){
            String args = getclass(ctx.castexpression());
            buftree.append(args);
        }

        setclass(ctx,buftree.toString());
        logger.info("exitDeleteexpression" + buftree.toString());
    }

    @Override
    public void exitNewexpression(CPP14Parser.NewexpressionContext ctx)
    {
        StringBuilder builder = new StringBuilder("new ");
        boolean isclassname = false;
        String classname = null;
        String initializer = null;

        if(ctx.newplacement()!=null){
            String args = ctx.newplacement().getText();
            builder.append(args);
            logger.info("newplacement\t\n"+args);
        }

        //todo : newtypeid is the class name
        if(ctx.newtypeid()!=null){
            classname = ctx.newtypeid().getText();
            builder.append(classname);
            logger.info("newtypeid\t\n"+classname);
        }

        if(ctx.newinitializer()!=null){
            initializer = ctx.newinitializer().getText();
            builder.append(initializer);
            logger.info("newinitializer\t\n"+initializer);
        }

        setclass(ctx, builder.toString());
        logger.info("Newexpression000\t\n"+getclass(ctx));
    }

    @Override
    public void exitCtorinitializer(CPP14Parser.CtorinitializerContext ctx)
    {
        if(ctx.meminitializerlist()!=null){
            String args = ctx.meminitializerlist().getText();
            logger.info("meminitializerlist\t\n"+args);
        }
    }

    @Override
    public void exitBlockdeclaration(CPP14Parser.BlockdeclarationContext ctx)
    {
        if(getclass(ctx.simpledeclaration())!=null) {
            String args = getclass(ctx.simpledeclaration());
            if(args!=null)
                args = args.concat("\n");

            setclass(ctx, args);
            logger.info("simpledeclaration000\t\n" + args);
        }

        if(ctx.usingdirective()!=null) {
            String args = ctx.usingdirective().getText();
            logger.info("usingdirective\t\n" + args);
        }



    }

    @Override
    public void exitSimpledeclaration(CPP14Parser.SimpledeclarationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        String type =null;
        String variable = null;
        if(ctx.declspecifierseq()!=null) {
            type = getclass(ctx.declspecifierseq());
            buftree.append(type);
            setclass(ctx, getclass(ctx.declspecifierseq()));
            logger.info("declspecifierseq\t\n" + getclass(ctx.declspecifierseq()));
        }
        if(ctx.initdeclaratorlist()!=null) {
            variable= getclass(ctx.initdeclaratorlist());
            buftree.append(variable+";\t");
            setclass(ctx, buftree.toString());
            logger.info("initdeclaratorlist\t\n" + buftree.toString());
        }

    }

    @Override
    public void exitInitdeclaratorlist(CPP14Parser.InitdeclaratorlistContext ctx) {
        StringBuilder buftree = new StringBuilder();
        if (ctx.initdeclaratorlist() != null) {
            String args = getclass(ctx.initdeclaratorlist());
            buftree.append(args + ",");
            logger.info("initdeclaratorlist\t\n" + getclass(ctx));
        }
        if (ctx.initdeclarator() != null) {
            String args = getclass(ctx.initdeclarator());
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitInitdeclaratorlist final\t\n" + buftree.toString());
    }

    @Override
    public void exitInitdeclarator(CPP14Parser.InitdeclaratorContext ctx) {
        StringBuilder buftree = new StringBuilder();
        if (ctx.declarator() != null) {
            String args = getclass(ctx.declarator());
            buftree.append(args);
            logger.info("initdeclarator: " + args);
        }
        if (ctx.initializer() != null) {
            String args = getclass(ctx.initializer());
            buftree.append(args);
            logger.info("initializer: " + args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitInitdeclarator: " + getclass(ctx));
    }

    @Override
    public void exitInitializer(CPP14Parser.InitializerContext ctx) {
        if (ctx.braceorequalinitializer() != null) {
            String args = getclass(ctx.braceorequalinitializer());
            setclass(ctx, args);
            logger.info("braceorequalinitializer\t\n" + args);
        }
        if (ctx.expressionlist() != null) {
            String args = ctx.expressionlist().getText();
            StringBuilder buftree = new StringBuilder();
            buftree.append("(" + args + ")");
            setclass(ctx, buftree.toString());
            logger.info("expressionlist\t\n" + args);
        }
    }

    @Override
    public void exitBraceorequalinitializer(CPP14Parser.BraceorequalinitializerContext ctx) {
        if (ctx.initializerclause() != null) {
            String args = getclass(ctx.initializerclause());
            StringBuilder buftree = new StringBuilder();
            buftree.append("=" + args);
            setclass(ctx, buftree.toString());
            logger.info("initializerclause\t\n" + args);
        }
        if (ctx.bracedinitlist() != null) {
            String args = getclass(ctx.bracedinitlist());
            setclass(ctx, args);
            logger.info("bracedinitlist111\t\n" + args);
        }
    }

    @Override public void exitBracedinitlist(CPP14Parser.BracedinitlistContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.LeftBrace()!=null)
            buftree.append(ctx.LeftBrace().getText());

        if(ctx.initializerlist()!=null){
            String args = getclass(ctx.initializerlist());
            buftree.append(args);
        }
        if(ctx.Comma()!=null)
            buftree.append(ctx.Comma().getText());
        if(ctx.RightBrace()!=null)
            buftree.append(ctx.RightBrace().getText());

        setclass(ctx, buftree.toString());
        logger.info("exitBracedinitlist final \t\n" + buftree.toString());
    }

    @Override
    public void exitInitializerlist(CPP14Parser.InitializerlistContext ctx)
    {
        StringBuilder buff = new StringBuilder();

        if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.DOMAINDEF)){
            if (ctx.initializerclause() != null){
                String args = getclass(ctx.initializerclause());
                if(directiveDef.getDirType().equals(Utility.directive.directiveType.PARAVAR)) {
                    if (paraVarAttr.getCurState() == pointerDataAttr.label.TYPE) {
                        paraVarAttr.setType(args);
                        paraVarAttr.setCurState(pointerDataAttr.label.VAR);
                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.VAR) {
                        paraVarAttr.setVariable(args);
                        paraVarAttr.setCurState(pointerDataAttr.label.SIZE);
                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.SIZE) {
                        paraVarAttr.setDataSize(args);
                        paraVarAttr.setCurState(pointerDataAttr.label.ATTR);
                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.ATTR) {
                        paraVarAttr.setAttribute(args);
                        paraVarAttr.setCurState(pointerDataAttr.label.STRIDE);

                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.STRIDE) {

                        paraVarAttr.setdmaWithStride(args.equals("yes"));
                        paraVarAttr.setCurState(pointerDataAttr.label.LDM);
                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.LDM) {
                        paraVarAttr.setldmByDma(args.equals("yes"));
                        paraVarAttr.setCurState(pointerDataAttr.label.SHARED);
                    } else if (paraVarAttr.getCurState() == pointerDataAttr.label.SHARED) {
                        paraVarAttr.setGlbSharedMem(args.equals("yes"));
                        paraVarAttr.setCurState(pointerDataAttr.label.TYPE);

                        if (paraVarAttr.getAttribute().equals("readonly") && paraVarAttr.getldmByDma())
                            paraVarAttr.setDefinedInCPE(true);
                        else if (paraVarAttr.getAttribute().equals("inout") || paraVarAttr.getAttribute().equals("outonly"))
                            paraVarAttr.setDefinedInCPE(true);

                        pointerDataAttr obj = new pointerDataAttr(paraVarAttr);
                        if(obj.getVariable().equals(atomAttr.getVariable()))
                            logger.info("atomic variable don't add to pointerDataAttrList: " + obj.getVariable());
                        else
                            utility.pointerDataAttrList.add(obj);
                        for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                            pointerDataAttr temp = utility.pointerDataAttrList.get(i);

                            if((temp.getAttribute().equals("inout") || temp.getAttribute().equals("outonly"))&&temp.getdmaWithStride())
                                utility.globalScopeDef.setDmaStride(true);
                            logger.info("pointerDataAttrList " + i + " type: " + temp.getType() + " var: " + temp.getVariable()
                                    + " size: " + temp.getDataSize() + " attr: " + temp.getAttribute() + " dmaWithStride: "
                                    + temp.getdmaWithStride() + " ldmByDma: " + temp.getldmByDma() + " GlbSharedMem: "
                                    + temp.getglbSharedMem() + " defineInCPE: " + temp.getDefinedInCPE());
                        }

                        /*
                        if (paraVarAttr.getAttribute().equals("inout") || paraVarAttr.getAttribute().equals("outonly")) {
                            if (!paraVarAttr.getglbSharedMem()) {
                                StringBuilder temp = new StringBuilder();
                                temp.append("__thread_local " + paraVarAttr.getType() + "* " + paraVarAttr.getVariable() + "_s;\n\n");
                                utility.globalDef.add(temp.toString());
                                logger.info("add globalDef local define: " + temp.toString());
                            }
                        }
                         */

                        //reset the object
                        paraVarAttr.setCurState(pointerDataAttr.label.TYPE);
                        paraVarAttr.setDefinedInCPE(false);
                    }
                }
                else if(directiveDef.getDirType().equals(Utility.directive.directiveType.ATOMVAR)){
                    logger.info("directiveDef state: " + atomAttr.getAtomState().toString());
                    if (atomAttr.getAtomState() == pointerDataAttr.atomPara.TYPE) {
                        atomAttr.setType(args);
                        atomAttr.setAtomState(pointerDataAttr.atomPara.VAR);
                    } else if (atomAttr.getAtomState() == pointerDataAttr.atomPara.VAR) {
                        atomAttr.setVariable(args);
                        atomAttr.setAtomState(pointerDataAttr.atomPara.SIZE);
                    } else if (atomAttr.getAtomState() == pointerDataAttr.atomPara.SIZE) {
                        atomAttr.setDataSize(args);
                        atomAttr.setAtomState(pointerDataAttr.atomPara.RCVCORE);
                    }else if (atomAttr.getAtomState() == pointerDataAttr.atomPara.RCVCORE) {
                        int corenum = Integer.parseInt(args);
                        atomAttr.setRcvCoreNum(corenum);
                        atomAttr.setAtomState(pointerDataAttr.atomPara.RMADATA);
                    } else if (atomAttr.getAtomState() == pointerDataAttr.atomPara.RMADATA) {
                        int datanum = Integer.parseInt(args);
                        atomAttr.setRmaDataNum(datanum);
                        atomAttr.setAtomState(pointerDataAttr.atomPara.COPYIN);
                    }else if (atomAttr.getAtomState() == pointerDataAttr.atomPara.COPYIN) {
                        atomAttr.setCopyin(args.equals("yes"));
                        atomAttr.setAtomState(pointerDataAttr.atomPara.TYPE);
                        logger.info("atomAttr type: " + atomAttr.getType() + " var: " + atomAttr.getVariable()
                                + " size: " + atomAttr.getDataSize() + " rcvcore: " + atomAttr.getRcvCoreNum()
                                + " rmadata: " + atomAttr.getRmaDataNum() + " copyIn: " + atomAttr.isCopyin());
                    }

                }
                else if(directiveDef.getDirType().equals(Utility.directive.directiveType.DATAREDIRECT)){
                    if(dataPatterns.getPatternState() == Utility.dataPattern.label.PATTERN1){
                        dataPatterns.setPattern1(args);
                        dataPatterns.setPatternState(Utility.dataPattern.label.PATTERN2);
                    }
                    else if(dataPatterns.getPatternState() == Utility.dataPattern.label.PATTERN2){
                        dataPatterns.setPattern2(args);
                        dataPatterns.setPatternState(Utility.dataPattern.label.PATTERN3);
                    }
                    else if(dataPatterns.getPatternState() == Utility.dataPattern.label.PATTERN3){
                        dataPatterns.setPattern3(args);
                        dataPatterns.setPatternState(Utility.dataPattern.label.VAR);
                    }
                    else if(dataPatterns.getPatternState() == Utility.dataPattern.label.VAR){
                        dataPatterns.setVariable(args);
                        dataPatterns.setPatternState(dataPattern.label.VARTYPE);
                    }
                    else if(dataPatterns.getPatternState() == Utility.dataPattern.label.VARTYPE){
                        dataPatterns.setVarType(args);
                        dataPatterns.setPatternState(Utility.dataPattern.label.USAGE);
                    }
                    else if(dataPatterns.getPatternState() == Utility.dataPattern.label.USAGE){
                        dataPatterns.setDataUsage(args);
                        dataPatterns.setPatternState(Utility.dataPattern.label.PATTERN1);

                        if(dataPatterns.getPattern2().equals("NONE"))
                            dataPatterns.setPattenType(Utility.dataPattern.type.ONEDIM);
                        else if(dataPatterns.getPattern3().equals("NONE"))
                            dataPatterns.setPattenType(Utility.dataPattern.type.TWODIM);
                        else
                            dataPatterns.setPattenType(dataPattern.type.THREEDIM);

                        dataPatterns.usageTranslate();
                        dataPattern obj = new dataPattern(dataPatterns);
                        dataPatternList.add(obj);

                        for (int i = 0; i < dataPatternList.size(); i++) {
                            dataPattern temp = dataPatternList.get(i);
                            //if dmawithstride, acquired the maximum dimensions of data stride
                            if(utility.globalScopeDef.getDmaStride())
                                utility.globalScopeDef.setMaxDim(temp.getPattenType());
                            logger.info("dataPatternList " + i + " patten1: " + temp.getPattern1() + " pattern2: " + temp.getPattern2()
                                    + " pattern3: " + temp.getPattern3() + " var: " + temp.getVariable() + " type: " +temp.getVarType() + " usage: "
                                    + temp.getDataUsage() + " maxDim: " + utility.globalScopeDef.getMaxDim());
                        }

                    }
                }


                logger.info("exitInitializerlist initializerclause: " + args + " state: " + paraVarAttr.getCurState());
            }

        }

        if (ctx.initializerlist() != null) {
            String args = getclass(ctx.initializerlist());
            if (args != null) {
                buff.append(args);
            }
        }

        if(ctx.Comma()!=null)
            buff.append(ctx.Comma().getText());

        if (ctx.initializerclause() != null) {
            String args = getclass(ctx.initializerclause());
            if (args != null) {
                buff.append(args);
            }
        }

        setclass(ctx, buff.toString());
        logger.info("exitInitializerlist final\t\n" + getclass(ctx));
    }

    @Override
    public void exitDeclspecifierseq(CPP14Parser.DeclspecifierseqContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.declspecifier()!=null) {
            String args = getclass(ctx.declspecifier());
            buftree.append(args + " ");
            setclass(ctx, buftree.toString());

            logger.info("exitDeclspecifierseq declspecifier: " + buftree.toString());
        }
        if(ctx.declspecifierseq()!=null) {
            String args = getclass(ctx.declspecifierseq());
            buftree.append(args);
            setclass(ctx, buftree.toString());
            logger.info("declspecifierseq111: \t\n" + buftree.toString());
        }

    }

    @Override
    public void exitDeclspecifier(CPP14Parser.DeclspecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.storageclassspecifier()!=null){
            String args = ctx.storageclassspecifier().getText();
            buftree.append(args);
        }
        if(ctx.typespecifier()!=null) {
            String args = getclass(ctx.typespecifier());
            buftree.append(args);
        }

        if(ctx.functionspecifier()!=null) {
            String args = ctx.functionspecifier().getText();
            buftree.append(args);
            logger.info("functionspecifier\t\n" + args);
        }

        if(ctx.Friend()!=null)
            buftree.append(ctx.Friend());
        if(ctx.Typedef()!=null)
            buftree.append(ctx.Typedef());
        if(ctx.Constexpr()!=null)
            buftree.append(ctx.Constexpr());

        setclass(ctx, buftree.toString());
        logger.info("exitDeclspecifier final\t\n" + buftree.toString());

    }

    @Override
    public void exitTypespecifier(CPP14Parser.TypespecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.baseclassspecifier()!=null) {
            logger.info("baseclassspecifier\t\n" + getclass(ctx.baseclassspecifier()));
            buftree.append(getclass(ctx.baseclassspecifier()));
        }

        if(ctx.inheritclassspecifier()!=null) {
            String args = getclass(ctx.inheritclassspecifier());
            buftree.append(args);
            logger.info("inheritclassspecifier\t\n" + args);
        }

        if(ctx.trailingtypespecifier()!=null) {
            String args = getclass(ctx.trailingtypespecifier());
            //remove restrct key word
            if(!args.contains("restrict"))
                buftree.append(args);
            logger.info("trailingtypespecifier\t\n" + args);
        }

        if(ctx.typedefspecifier()!=null) {
            String args = getclass(ctx.typedefspecifier());
            buftree.append(args);
            logger.info("typedefspecifier\t\n" + args);
        }

        if(ctx.inherittypedefspecifier()!=null) {
            String args = getclass(ctx.inherittypedefspecifier());
            buftree.append(args);
            logger.info("inherittypedefspecifier\t\n" + args);
        }

        if(ctx.enumspecifier()!=null) {
            String args = getclass(ctx.enumspecifier());
            buftree.append(args);
            logger.info("enumspecifier\t\n" + args);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitTypespecifier final\t\n" + buftree.toString());

    }

    @Override
    public void exitTypedefspecifier(CPP14Parser.TypedefspecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.typestructhead()!=null){
            String args = getclass(ctx.typestructhead());
            buftree.append(args+" ");
            //setclass(ctx, getclass(ctx.declaration()));
            logger.info("typestructhead\t\n"+args);
        }

        if(ctx.memberspecification()!=null){
            String args = getclass(ctx.memberspecification());
            buftree.append("{\t\n"+ args);
            logger.info("typedef memberspecification\t\n"+args);
        }
        if(ctx.RightBrace()!=null)
            buftree.append("\t\n"+ctx.RightBrace().getText());

        if(ctx.typedefname()!=null){
            String args = ctx.typedefname().getText();
            buftree.append(args+";\t\n");
            logger.info("typedefname\t\n"+args);
        }

        setclass(ctx, buftree.toString());

        logger.info("exitTypedefspecifier final\t\n"+getclass(ctx));

    }

    @Override public void exitTypestructhead(CPP14Parser.TypestructheadContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.typestructkey()!=null) {
            String args = getclass(ctx.typestructkey());
            buftree.append(args+" ");
        }
        if(ctx.structname()!=null){
            String args = ctx.structname().getText();
            buftree.append(args);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitTypestructhead final: "+buftree.toString());
    }

    @Override public void exitTypestructkey(CPP14Parser.TypestructkeyContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Typedef()!=null) {
            buftree.append(ctx.Typedef().getText());
            buftree.append(" ");
        }
        if(ctx.Struct()!=null) {
            buftree.append(ctx.Struct().getText());
        }
        setclass(ctx, buftree.toString());
        logger.info("exitTypestructkey0\t\n"+getclass(ctx));
    }

    @Override
    public void exitTrailingtypespecifier(CPP14Parser.TrailingtypespecifierContext ctx)
    {
        if(ctx.simpletypespecifier()!=null) {
            String args = getclass(ctx.simpletypespecifier());
            setclass(ctx, args);
            logger.info("simpletypespecifier\t\n" + args);
        }
        if(ctx.elaboratedtypespecifier()!=null) {
            String args = getclass(ctx.elaboratedtypespecifier());
            setclass(ctx, args);
            logger.info("elaboratedtypespecifier\t\n" + args);
        }

        if(ctx.typenamespecifier()!=null) {
            String args = ctx.typenamespecifier().getText();
            setclass(ctx, args);
            logger.info("typenamespecifier\t\n" + args);
        }

        if(ctx.cvqualifier()!=null) {
            String args = ctx.cvqualifier().getText();
            setclass(ctx, args);
            logger.info("cvqualifier\t\n" + args);
        }
    }
    @Override
    public void exitSimpletypespecifier(CPP14Parser.SimpletypespecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        Token semi = ctx.getStop();
        int i = semi.getTokenIndex();

        logger.info("exitSimpletypespecifier getTokenIndex: " + i);
        List<Token> includeChannel = Cpptokens.getHiddenTokensToLeft(i, CPP14Lexer.INCLUDE);
        if(includeChannel!=null) {
            if(!swPredefineAlreadyIn) {
                // add athread unique include list
                for (int j = 0; j < utility.includedefinelist.size(); j++)
                    buftree.append(utility.includedefinelist.get(j));
            }

            for (int j = 0; j < includeChannel.size(); j++) {
                Token cmt = includeChannel.get(j);
                buftree.append(cmt.getText() + "\t\n");
                logger.info("exitSimpletypespecifier getHiddenTokensToLeft\t\n" + cmt.getText());
            }
            if(!swPredefineAlreadyIn) {

                // add athread dma global definition
                for (int j = 0; j < utility.athreadDMA.size(); j++)
                    buftree.append(utility.athreadDMA.get(j));

                swPredefineAlreadyIn = true;
            }
        }

        if(ctx.nestednamespecifier()!=null){
            String args = ctx.nestednamespecifier().getText();
            logger.info("exitSimpletypespecifier nestednamespecifier \t\n" + args);
            buftree.append(args);
        }
        if(ctx.Typedef()!=null)
            buftree.append(ctx.Typedef()+" ");
        if(ctx.thetypename()!=null) {
            String args = ctx.thetypename().getText();

            logger.info("exitSimpletypespecifier thetypename \t\n" + args);
            if(args.contains("__global__")) {
                utility.globalScopeDef.setScope(Utility.globalScope.glbScope.KERNERENTRY);
                logger.info("exitSimpletypespecifier: kernel global is abandoned \t\n" + args);
            }
            else if(args.contains("__device__")){
                utility.globalScopeDef.setScope(Utility.globalScope.glbScope.DEVFUNC);
                logger.info("exitSimpletypespecifier: kernel device is abandoned \t\n" + args);
            }
            else if (args.contains("__userDef__")) {
                utility.globalScopeDef.setScope(Utility.globalScope.glbScope.DOMAINDEF);
                buftree.append("//" + args);
            }
            else
                buftree.append(args);
        }
        if(ctx.Template()!=null)
            buftree.append(ctx.Template());
        if(ctx.simpletemplateid()!=null){
            String args = ctx.simpletemplateid().getText();
            buftree.append(args);
        }
        if(ctx.Char()!=null)
            buftree.append(ctx.Char());
        if(ctx.Char16()!=null)
            buftree.append(ctx.Char16());
        if(ctx.Char32()!=null)
            buftree.append(ctx.Char32());
        if(ctx.Wchar()!=null)
            buftree.append(ctx.Wchar());
        if(ctx.Bool()!=null)
            buftree.append(ctx.Bool());
        if(ctx.Short()!=null)
            buftree.append(ctx.Short());
        if(ctx.Int()!=null)
            buftree.append(ctx.Int());
        if(ctx.Long()!=null)
            buftree.append(ctx.Long());
        if(ctx.Signed()!=null)
            buftree.append(ctx.Signed());
        if(ctx.Unsigned()!=null)
            buftree.append(ctx.Unsigned());
        if(ctx.Float()!=null)
            buftree.append(ctx.Float());
        if(ctx.Double()!=null)
            buftree.append(ctx.Double());
        if(ctx.Void()!=null)
            buftree.append(ctx.Void());
        if(ctx.Auto()!=null)
            buftree.append(ctx.Auto());
        if(ctx.Struct()!=null)
            buftree.append(ctx.Struct());
        if(ctx.decltypespecifier()!=null){
            String args = ctx.decltypespecifier().getText();
            logger.info("exitSimpletypespecifier decltypespecifier \t\n" + args);
            buftree.append(args);
        }

        setclass(ctx, buftree.toString());
        logger.info("exitSimpletypespecifier final \t\n" + buftree.toString());
    }

    @Override
    public void exitElaboratedtypespecifier(CPP14Parser.ElaboratedtypespecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Template()!=null) {
            String args = ctx.Template().getText();
            // for distinguish:  classkey nestednamespecifier Template? simpletemplateid
            if(ctx.nestednamespecifier()==null) {
                buftree.append(args + " ");
                logger.info("Template: " + args);
            }
        }
        if(ctx.classkey()!=null) {
            String args = ctx.classkey().getText();
            buftree.append(args+" ");
            logger.info("classkey: " + args);
        }
        if(ctx.attributespecifierseq()!=null) {
            String args = ctx.attributespecifierseq().getText();
            buftree.append(args+" ");
            logger.info("attributespecifierseq: " + args);
        }

        if(ctx.Enum()!=null) {
            String args = ctx.Enum().getText();
            buftree.append(args+" ");
            logger.info("Enum\t\n" + args);
        }

        if(ctx.nestednamespecifier()!=null) {
            String args = ctx.nestednamespecifier().getText();
            buftree.append(args+" ");
            logger.info("nestednamespecifier: " + args);
        }

        if(ctx.Identifier()!=null) {
            String args = ctx.Identifier().getText();
            buftree.append(args+"\t\n");
            logger.info("Identifier\t\n" + args);
        }

        if(ctx.simpletemplateid()!=null) {
            String args = ctx.simpletemplateid().getText();
            if(ctx.nestednamespecifier()!=null){
                if(ctx.Template()!=null){
                    buftree.append(ctx.Template().getText()+" ");
                }
            }
            buftree.append(args+"\t\n");
            logger.info("simpletemplateid\t\n" + args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitElaboratedtypespecifier\t\n" + buftree.toString());
    }

    @Override
    public void exitEnumspecifier(CPP14Parser.EnumspecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.enumhead()!=null){
            String args = getclass(ctx.enumhead());
            logger.info("enumhead\t\n"+args);
            buftree.append(args);
        }
        if(ctx.LeftBrace()!=null)
            buftree.append(ctx.LeftBrace());
        if(ctx.enumeratorlist()!=null){
            String args = getclass(ctx.enumeratorlist());
            logger.info("exitEnumspecifier enumeratorlist\t\n"+args);
            buftree.append(args);
        }
        if(ctx.Comma()!=null)
            buftree.append(ctx.Comma());

        if(ctx.RightBrace()!=null)
            buftree.append(ctx.RightBrace()+";\n");

        setclass(ctx, buftree.toString());
        logger.info("exitEnumspecifier final\t\n" + buftree.toString());
    }
    @Override
    public void exitEnumhead(CPP14Parser.EnumheadContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.enumkey()!=null){
            String args = getclass(ctx.enumkey());
            logger.info("enumkey\t\n"+args);
            buftree.append(args+" ");
        }
        if(ctx.nestednamespecifier()!=null){
            String args = ctx.nestednamespecifier().getText();
            logger.info("nestednamespecifier\t\n"+args);
            buftree.append(args);
        }
        if(ctx.Identifier()!=null)
            buftree.append(ctx.Identifier());
/*
		if(ctx.enumbase()!=null){
			String args = getclass(ctx.enumbase());
			logger.info("enumbase\t\n"+args);
			buftree.append(args);
		}
 */
        setclass(ctx, buftree.toString());
        logger.info("exitEnumhead final\t\n" + getclass(ctx));
    }
    @Override
    public void exitEnumkey(CPP14Parser.EnumkeyContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Enum()!=null)
            buftree.append(ctx.Enum());
        if(ctx.Class()!=null)
            buftree.append(" "+ ctx.Class());
        if(ctx.Struct()!=null)
            buftree.append(" "+ ctx.Struct());
        setclass(ctx, buftree.toString());
        logger.info("exitEnumkey final\t\n" + getclass(ctx));
    }

    @Override
    public void exitEnumeratorlist(CPP14Parser.EnumeratorlistContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.enumeratorlist()!=null){
            String args = getclass(ctx.enumeratorlist());
            logger.info("enumeratorlist\t\n"+args);
            buftree.append(args+",");
        }
        if(ctx.enumeratordefinition()!=null){
            String args = getclass(ctx.enumeratordefinition());
            logger.info("enumeratordefinition\t\n"+args);
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitEnumeratorlist final\t\n" + getclass(ctx));
    }

    @Override
    public void exitEnumeratordefinition(CPP14Parser.EnumeratordefinitionContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.enumerator()!=null){
            buftree.append(ctx.enumerator().getText());
        }
        if(ctx.Assign()!=null)
            buftree.append(ctx.Assign());
        if(ctx.constantexpression()!=null){
            String args = ctx.constantexpression().getText();
            logger.info("constantexpression\t\n"+args);
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitEnumeratordefinition final\t\n" + getclass(ctx));

    }

    @Override
    public void exitInheritclassspecifier(CPP14Parser.InheritclassspecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.classhead()!=null){
            String args = getclass(ctx.classhead());
            logger.info("inherit classspecifier\t\n"+args);
            buftree.append(args);
        }
        if(ctx.memberspecification()!=null){
            String args = getclass(ctx.memberspecification());
            setclass(ctx, args);
            logger.info("inherit class body\t\n"+args);
            buftree.append(getclass(ctx.memberspecification()));
            buftree.append("};\t\n");
        }
        setclass(ctx, buftree.toString());
        logger.info("exitInheritclassspecifier tree\t\n" + getclass(ctx));

    }

    @Override public void exitClasshead(CPP14Parser.ClassheadContext ctx)
    {
        String args =null;
        String basename = null;
        StringBuilder buftree = new StringBuilder();
        if(ctx.classheadname()!=null){
            args = ctx.classheadname().getText();
            //change to inherit class as struct for c++
            //buftree.append("\tstruct ");
            buftree.append(args);
            //buftree.append("{\t\n");
            setclass(ctx, buftree.toString());
            logger.info("classheadname: " + getclass(ctx));
        }

        if(ctx.baseclause()!=null){
            basename = getclass(ctx.baseclause().basespecifierlist());
            //it maybe interit template base classs, need to modified
            //for example: class ACCStream : public Stream<T>
            // basename here is parsed to  Stream<T>
            if(basename.contains("<"))
                basename = basename.substring(0, basename.indexOf("<"));
            logger.info("inherit baseclause: "+basename);
        }

    }

    @Override
    public void exitBaseclassspecifier(CPP14Parser.BaseclassspecifierContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        String args;
        if(ctx.baseclasshead()!=null){
            args = ctx.baseclasshead().getText();
            logger.info("baseclasshead\t\n" + args);
            logger.info("baseclasshead tree\t\n" + getclass(ctx.baseclasshead()));
            buftree.append(getclass(ctx.baseclasshead()));
        }
        if(ctx.memberspecification()!=null) {
            args = getclass(ctx.memberspecification());
            setclass(ctx, args);
            logger.info("memberdeclaration000\t\n"+getclass(ctx.memberspecification()));
            buftree.append(getclass(ctx.memberspecification()));
            buftree.append("};\t\n");
        }
        setclass(ctx, buftree.toString());

        logger.info("memberspecification tree\t\n" + getclass(ctx));
    }

    @Override
    public void exitInherittypedefspecifier(CPP14Parser.InherittypedefspecifierContext ctx)
    {

        StringBuilder buftree = new StringBuilder();
        if(ctx.inheritstructhead()!=null){
            String args = getclass(ctx.inheritstructhead());
            buftree.append(args+" ");
            //setclass(ctx, getclass(ctx.declaration()));
            logger.info("inheritstructhead\t\n"+args);
        }

        if(ctx.memberspecification()!=null){
            String args = getclass(ctx.memberspecification());
            buftree.append("{\t\n"+ args);
            logger.info("typedef memberspecification\t\n"+args);
        }
        if(ctx.RightBrace()!=null)
            buftree.append("\t\n"+ctx.RightBrace().getText());

        if(ctx.typedefname()!=null){
            String args = ctx.typedefname().getText();
            buftree.append(args+";\t\n");
            logger.info("typedefname\t\n"+args);
        }

        setclass(ctx, buftree.toString());

        logger.info("exitInherittypedefspecifier final\t\n"+getclass(ctx));
    }

    @Override
    public void exitInheritstructhead(CPP14Parser.InheritstructheadContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        String basename = null;
        String structname = null;
        if(ctx.typestructkey()!=null){
            String args = getclass(ctx.typestructkey());
            buftree.append(args+" ");
        }

        if(ctx.structname()!=null){
            structname = ctx.structname().getText();
            buftree.append(structname);
            utility.curclassname = structname;
        }

        if(ctx.baseclause()!=null){
            basename = getclass(ctx.baseclause().basespecifierlist());
            //it maybe interit template base classs, need to modified
            //for example: class ACCStream : public Stream<T>
            // basename here is parsed to  Stream<T>
            if(basename.contains("<"))
                basename = basename.substring(0, basename.indexOf("<"));
            logger.info("inherit struct baseclause: " + basename);
        }

        if((structname!=null)&&(basename!=null)) {
            // save the inherit class name and base class name together
            utility.inheritclass.put(structname, basename);
            for(int i=0; i<utility.abstractclassname.size();i++){
                if(basename.equals(utility.abstractclassname.get(i))){
                    utility.absinheritclass.put(structname,basename);
                    logger.info("abstract inherit class: "+basename+structname);
                }
            }
        }

        setclass(ctx, buftree.toString());
        logger.info("exitInheritstructhead final: "+buftree.toString());
    }


    @Override
    public void exitBaseclasshead(CPP14Parser.BaseclassheadContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.classkey()!=null){
            String args = ctx.classkey().getText();
            buftree.append(args + " ");
        }
        if(ctx.classheadname()!=null){
            String args = ctx.classheadname().getText();
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());

        //save class name
        logger.info("exitBaseclasshead:" + getclass(ctx));
    }

    @Override
    public void exitMemberspecification(CPP14Parser.MemberspecificationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.memberdeclaration()!=null) {
            String args = getclass(ctx.memberdeclaration());
            logger.info("memberdeclaration111-1\t\n"+args);
            if(getclass(ctx.memberdeclaration())!=null)
                buftree.append(args);
        }
        if(ctx.memberspecification()!=null) {
            String args = getclass(ctx.memberspecification());
            logger.info("memberspecification111-22\t\n"+args);
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitMemberspecification final\t\n"+buftree.toString());
    }

    @Override
    public void exitMemberdeclaration(CPP14Parser.MemberdeclarationContext ctx)
    {
        StringBuilder mbrbuilder = new StringBuilder();

        String decltype = null;

        if(ctx.declspecifierseq()!=null){
            String args = getclass(ctx.declspecifierseq());
            decltype = args;
            logger.info("declspecifierseq222: "+args);
            mbrbuilder.append("\t"+args+" ");
        }
        else {
            mbrbuilder.append("\t void ");
        }

        if(ctx.restricttypelist()!=null){
            String args = getclass(ctx.restricttypelist());
            mbrbuilder.append(args);
            logger.info("restricttypelist222: "+args);
        }

        if(ctx.memberdeclaratorlist()!=null){
            String args = getclass(ctx.memberdeclaratorlist());
            mbrbuilder.append(getclass(ctx.memberdeclaratorlist()));
            mbrbuilder.append(";\t\n");

            setclass(ctx, mbrbuilder.toString());
            logger.info("memberdeclaratorlist222final\t\n"+args);
        }

        if(ctx.functiondefinition()!=null){
            String args = getclass(ctx.functiondefinition());
            String funcname = args.substring(0,args.indexOf("("));
            String funchead = args.substring(0, args.indexOf("{"));
            if(funcname.contains(" "))
                funcname = funcname.substring(funcname.lastIndexOf(" ")+1);
            if(funcname.contains("*"))
                funcname = funcname.replace("*", "");
            logger.info("memberdeclarator funcname is "+funcname+ " funchead: "+funchead);

        }

        if(ctx.templatedeclaration()!=null){
            String args = ctx.templatedeclaration().getText();
            logger.info("exitMemberdeclaration templatedeclaration\t\n"+args);
        }
    }

    @Override
    public void exitRestricttypelist(CPP14Parser.RestricttypelistContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.restricttypelist()!=null){
            String args = getclass(ctx.restricttypelist());
            buftree.append(args);
        }
        if(ctx.restricttype()!=null){
            String args = getclass(ctx.restricttype());
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitRestricttypelist final\t\n"+buftree.toString());
    }

    @Override
    public void exitRestricttype(CPP14Parser.RestricttypeContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.Star()!=null)
            buftree.append(ctx.Star());
        if(ctx.Const()!=null)
            buftree.append(ctx.Const()+" ");

        setclass(ctx, buftree.toString());
        logger.info("exitRestricttype final\t\n"+buftree.toString());
    }


    @Override
    public void exitMemberdeclaratorlist(CPP14Parser.MemberdeclaratorlistContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.memberdeclaratorlist()!=null){
            String args = getclass(ctx.memberdeclaratorlist());
            buftree.append(args);
        }
        if(ctx.Comma()!=null)
            buftree.append(ctx.Comma());

        if(ctx.memberdeclarator()!=null){
            String args = getclass(ctx.memberdeclarator());
            buftree.append(args);
            setclass(ctx, buftree.toString());
            logger.info("exitMemberdeclaratorlist final\t"+buftree.toString());
        }
    }

    @Override public void exitMemberdeclarator(CPP14Parser.MemberdeclaratorContext ctx)
    {
        if(ctx.declarator()!=null){
            String args = ctx.declarator().getText();
            logger.info("declarator333 "+args);
            setclass(ctx, getclass(ctx.declarator()));
            logger.info("declarator444 "+getclass(ctx.declarator()));
        }
        if(ctx.braceorequalinitializer()!=null){
            String args = ctx.braceorequalinitializer().getText();
            logger.info("braceorequalinitializer class name \t"+args);
        }
    }

    @Override
    public void exitDeclarator(CPP14Parser.DeclaratorContext ctx)
    {
        if(ctx.ptrdeclarator()!=null){
            String args = getclass(ctx.ptrdeclarator());
            setclass(ctx, args);
            logger.info("ptrdeclarator333final "+args);
        }
    }

    @Override
    public void exitPtrdeclarator(CPP14Parser.PtrdeclaratorContext ctx)
    {
        StringBuilder buftree = new StringBuilder();

        if(ctx.noptrdeclarator()!=null){
            String args = getclass(ctx.noptrdeclarator());
            //for the destructor function declaration, we need to change ~ to exit
            //for example: ~ACCStream() to ACCStream()
//            if(args.contains("~"))
//                buftree.append(args.replace("~", "exit"));
//            else
//                buftree.append(args);
            setclass(ctx, args);

            if(ctx.noptrdeclarator().parametersandqualifiers()!=null){
                //function name can be parse
                // for example: ResultDatabase::Result::GetMin(struct Resultqnlm-type *ResultStr)
            }

            logger.info("exitPtrdeclarator noptrdeclarator: \t\n"+args);
        }

        if(ctx.ptroperator()!=null){
            String args = ctx.ptroperator().getText();
            buftree.append(args);
            logger.info("exitPtrdeclarator ptroperator\t\n"+args);
        }

        if(ctx.ptrdeclarator()!=null){
            String args = getclass(ctx.ptrdeclarator());
            buftree.append(args);
            setclass(ctx, buftree.toString());
            logger.info("exitPtrdeclarator ptrdeclarator\t\n"+args);
        }


    }


    public void exitNoptrdeclarator(CPP14Parser.NoptrdeclaratorContext ctx)
    {
        StringBuilder builder = new StringBuilder();
        if(ctx.declaratorid()!=null){
            String args = ctx.declaratorid().getText();
            builder.append(args);
            logger.info("declaratorid444: "+args);
            if(args.contains("~")&&args.contains("(")) {
                utility.curclassname = args.substring(args.indexOf("~") + 1, args.indexOf("(:)"));
                logger.info("declaratorid444+3\t\n" + utility.curclassname);
            }
        }
        //this function is recognized as function declaration
        if(ctx.noptrdeclarator()!=null){
            String args = getclass(ctx.noptrdeclarator());
            logger.info("noptrdeclarator444+1\t" +args+"\t"+utility.globalScopeDef.getScope().toString());
            builder.append(args);
        }

        //all the function declaration parameter should be reorganized here
        if(ctx.parametersandqualifiers()!=null){
            String args = getclass(ctx.parametersandqualifiers());
            builder.append(args);
            logger.info("parametersandqualifiers555\t\n"+args);

        }
        if(ctx.LeftBracket()!=null){
            builder.append(ctx.LeftBracket().getText());
        }
        if(ctx.constantexpression()!=null){
            String args = ctx.constantexpression().getText();
            builder.append(args);
        }
        if(ctx.RightBracket()!=null){
            builder.append(ctx.RightBracket().getText());
        }
        if(ctx.attributespecifierseq()!=null){
            String args = ctx.attributespecifierseq().getText();
            builder.append(args);
        }

        if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.DOMAINDEF)){
            if(builder.toString().equals("paraVarAttr"))
                directiveDef.setDirType(Utility.directive.directiveType.PARAVAR);
            else if(builder.toString().equals("getAtomOpr")) {
                directiveDef.setDirType(Utility.directive.directiveType.ATOMVAR);
                directiveDef.setAtomOpr(true);
            }
            else if(builder.toString().equals("dataPattern")){
                directiveDef.setDirType(Utility.directive.directiveType.DATAREDIRECT);
            }
            logger.info("directiveDef: " + directiveDef.getDirType().toString());
        }
        setclass(ctx, builder.toString());
        logger.info("exitNoptrdeclarator final\t\n"+builder.toString());


    }

    //for parameter parse routine
    @Override
    public void exitParametersandqualifiers(CPP14Parser.ParametersandqualifiersContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.LeftParen()!=null)
            buftree.append(ctx.LeftParen().getText());

        if(ctx.parameterdeclarationclause()!=null){
            String args = getclass(ctx.parameterdeclarationclause());
            if(args!=null)
                buftree.append(args);
        }
        if(ctx.RightParen()!=null)
            buftree.append(ctx.RightParen().getText());

        if(ctx.cvqualifierseq()!=null){
            String args = getclass(ctx.cvqualifierseq());
            buftree.append(args);
        }
        setclass(ctx, buftree.toString());

        logger.info("exitParametersandqualifiers final\t\n"+buftree.toString());
    }

    @Override
    public void exitParameterdeclarationclause(CPP14Parser.ParameterdeclarationclauseContext ctx)
    {
        if(ctx.parameterdeclarationlist()!=null){
            String args = getclass(ctx.parameterdeclarationlist());
            if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)) {
                //Atherad kernel function, the parameter should be single pointer
                //for example: void kernelFunc(Para *Paras)
                setclass(ctx, "Para *Paras");
            }
            else {
                setclass(ctx, args);
                logger.info("parameterdeclarationlist1\t\n" + args);
            }
        }
    }

    @Override
    public void exitParameterdeclarationlist(CPP14Parser.ParameterdeclarationlistContext ctx)
    {
        StringBuilder temp = new StringBuilder();
        /* for the bellowing recursive parse, first to push declaration to the stack,
         * then following the list, using ", " as the interval.
         *			parameterdeclarationlist
         *		  	: parameterdeclaration
         *		  	| parameterdeclarationlist ',' parameterdeclaration
         */
        if(ctx.parameterdeclarationlist()!=null){
            temp.append(getclass(ctx.parameterdeclarationlist()));
            temp.append(", ");
            logger.info("parameterdeclarationlist000\t"+getclass(ctx.parameterdeclarationlist()));

        }

        if(ctx.parameterdeclaration()!=null){

            //temp.append(",");
            temp.append(getclass(ctx.parameterdeclaration()));
            setclass(ctx, temp.toString());
            logger.info("parameterdeclaration111\t"+getclass(ctx.parameterdeclaration()));
        }
    }

    @Override
    public void exitParameterdeclaration(CPP14Parser.ParameterdeclarationContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.cvqualifierseq()!=null){
            String args = getclass(ctx.cvqualifierseq());
            buftree.append(args+" ");
        }
        if(ctx.declspecifierseq()!=null){
            String args = getclass(ctx.declspecifierseq());
            logger.info("Parameterdeclarationdeclspecifierseq\t\n"+args);
            buftree.append(args);
        }
        if(ctx.declarator()!=null){
            String args1 = ctx.declarator().getText();
            logger.info("declarator\t\n"+args1);
            buftree.append(args1);
        }
        if(ctx.abstractdeclarator()!=null){
            String args1 = ctx.abstractdeclarator().getText();
            logger.info("abstractdeclarator\t\n"+args1);
            buftree.append(args1);
        }

        if(ctx.Assign()!=null)
            buftree.append(ctx.Assign());

        if(ctx.initializerclause()!=null){
            String args = getclass(ctx.initializerclause());
            buftree.append(args);
        }

        //kernelPara is recorded for Para declaration
        if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY))
            utility.kernelPara.add(buftree.toString());

        setclass(ctx, buftree.toString());
        logger.info("exitParameterdeclaration\t\n"+ buftree.toString());

    }

    @Override
    public void exitCvqualifierseq(CPP14Parser.CvqualifierseqContext ctx)
    {
        StringBuilder buftree = new StringBuilder();
        if(ctx.cvqualifier()!=null)
            buftree.append(ctx.cvqualifier().getText());

        if(ctx.cvqualifierseq()!=null){
            String args = getclass(ctx.cvqualifierseq());
            buftree.append(" "+args);
        }
        setclass(ctx, buftree.toString());
        logger.info("exitCvqualifierseq final \t\n"+ buftree.toString());

    }


    @Override
    public void exitPostfixexpression(CPP14Parser.PostfixexpressionContext ctx) {
        StringBuilder buftree = new StringBuilder();
        String swTranslate = null;
        String postfix = null;

        logger.info("enter exitPostfixexpression");

        if (ctx.primaryexpression() != null) {
            String args = getclass(ctx.primaryexpression());
            buftree.append(args);
            logger.info("primaryexpression: " + args);
        }
        if (ctx.postfixexpression() != null) {
            String args = getclass(ctx.postfixexpression());
            //postfixexpression '++'
            if (ctx.PlusPlus() != null) {
                buftree.append(args + "++");
                //    setclass(ctx, buftree.toString());
            } else if (ctx.MinusMinus() != null) {
                buftree.append(args + "--");
            } else if(ctx.expressionlist()==null){
                buftree.append(args);
                if(ctx.LeftParen()!=null)
                    buftree.append("(");
                if(ctx.RightParen()!=null)
                    buftree.append(")");
            }
            else
                buftree.append(args);
            postfix = buftree.toString();
            logger.info("postfixexpression: " + buftree.toString() + " postfix: " +  postfix);
        }
        if (ctx.simpletypespecifier() != null) {
            String args = ctx.simpletypespecifier().getText();
            buftree.append(args);
            logger.info("simpletypespecifier: " + args);
        }
        if (ctx.typenamespecifier() != null) {
            String args = ctx.typenamespecifier().getText();
            buftree.append(args);
            logger.info("typenamespecifier: " + args);
        }
        if (ctx.expressionlist() != null) {
            String args = getclass(ctx.expressionlist().initializerlist());

            buftree.append("(" + args + ")");
            logger.info("exitPostfixexpression00 expressionlist: " + buftree.toString());
        }
        if (ctx.bracedinitlist() != null) {
            String args = getclass(ctx.bracedinitlist());
            //postfixexpression '[' bracedinitlist ']'
            if (ctx.postfixexpression() != null)
                buftree.append("[" + args + "]");
                //simpletypespecifier bracedinitlist  typenamespecifier bracedinitlist
            else
                buftree.append(args);
            // setclass(ctx, buftree.toString());
            logger.info("bracedinitlist " + args);
        }
        if (ctx.typeidofthetypeid() != null) {
            String args = ctx.typeidofthetypeid().getText();
            buftree.append(args);
            logger.info("typeidofthetypeid " + args);
        }
        if (ctx.Dynamic_cast() != null) {
            String args = ctx.Dynamic_cast().getText();
            buftree.append(args);
            logger.info("Dynamic_cast " + args);
        }
        if (ctx.Static_cast() != null) {
            String args = ctx.Static_cast().getText();
            buftree.append(args);
            logger.info("Static_cast " + args);
        }
        if (ctx.Reinterpret_cast() != null) {
            String args = ctx.Reinterpret_cast().getText();
            buftree.append(args);
            logger.info("Reinterpret_cast " + args);
        }
        if (ctx.Const_cast() != null) {
            String args = ctx.Const_cast().getText();
            buftree.append(args);
            logger.info("Const_cast " + args);
        }
        if (ctx.thetypeid() != null) {
            String args = ctx.thetypeid().getText();
            //typeidofthetypeid '(' thetypeid ')'
            if (ctx.typeidofthetypeid() != null) {
                buftree.append("(" + args + ")");
                //setclass(ctx, buftree.toString());
            } else
                /* Dynamic_cast '<' thetypeid '>' '(' expression ')'
                 * Static_cast '<' thetypeid '>' '(' expression ')'
                 * Reinterpret_cast '<' thetypeid '>' '(' expression ')'
                 * Const_cast '<' thetypeid '>' '(' expression ')'
                 */
                buftree.append("<" + args + ">");
            logger.info("thetypeid: " + args);
        }
        if (ctx.expression() != null) {
            String args = getclass(ctx.expression());
            //postfixexpression '[' expression ']'
            if (ctx.LeftBracket() != null) {
                // data locality check and translation
                logger.info("datausage: " + dataPatterns.getDataUsage() + " postfix: " + postfix);
                if(dataPatterns.getDataUsage()!=null) {
                    if (dataPatterns.getDataUsage().equals(args) && (postfix.contains("_s"))) {
                        String tmpStr = postfix.replace("_s", "");
                        String usage = dataPatterns.getDataUsage();
                        for (int i = 0; i < utility.pointerDataAttrList.size(); i++) {
                            pointerDataAttr obj = utility.pointerDataAttrList.get(i);
                            logger.info("data locality: " + postfix + " tmpStr: " + tmpStr + " objVar: " + obj.getVariable());
                            if (tmpStr.equals(obj.getVariable())) {
                                if (obj.getAttribute().equals("inout") || obj.getAttribute().equals("outonly")) {
                                    args = args.replace(usage, "threadId_x");
                                }
                            }
                        }
                    }
                }
                buftree.append("[" + args + "]");
            }
            else
                //Dynamic_cast '<' thetypeid '>' '(' expression ')'
                buftree.append("(" + args + ")");
            // setclass(ctx, buftree.toString());
            logger.info("expressionsec000: " + args);
        }

        if (ctx.idexpression() != null) {
            String args = ctx.idexpression().getText();

            //postfixexpression '.' Template? idexpression
            if (ctx.Dot() != null) {
                if (ctx.Template() != null)
                    buftree.append("." + ctx.Template().getText() + args);
                else
                    buftree.append("." + args);
            } else if (ctx.Arrow() != null) {
                //postfixexpression '->' Template? idexpression
                if (ctx.Template() != null)
                    buftree.append("->" + ctx.Template().getText() + args);
                else
                    buftree.append("->" + args);
            }
            swTranslate =  utility.sunwayTranslation(buftree.toString());

            if((utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY))&&(swTranslate==null)){
                for(int i=0; i<utility.pointerDataAttrList.size(); i++){
                    pointerDataAttr obj  = utility.pointerDataAttrList.get(i);
                    logger.info("find in pointerDataAttrList: " + obj.getVariable()  + " args: " + args +
                            " isAtomOpr: " + directiveDef.isAtomOpr());
                    if(directiveDef.isAtomOpr()) {
                        if (args.equals(atomAttr.getVariable()))
                            logger.info("exitPostfixexpression find atomic variable:" + args + " keep no change");
                    }
                    else if(args.equals(obj.getVariable())){
                        if(obj.getAttribute().equals("readonly")) {
                            if (obj.getDefinedInCPE())
                                //args = obj.getVariable() + "_s";
                                buftree.append("_s");
                            else
                                //args = "Para_s->" + obj.getVariable();
                                buftree.insert(0,"Para_s->");
                        }
                        else if(obj.getAttribute().equals("inout") || obj.getAttribute().equals("outonly"))
                            //args = obj.getVariable() + "_s";
                            buftree.append("_s");
                        logger.info("exitPostfixexpression find pointerdata: " + buftree.toString());
                    }
                }
            }

            //setclass(ctx, buftree.toString());
            logger.info("idexpression: " + buftree.toString() + " scope:" + utility.globalScopeDef.getScope().toString() +
                    " swTranslate: " + swTranslate);
        }
        if (ctx.pseudodestructorname() != null) {
            String args = ctx.pseudodestructorname().getText();
            //postfixexpression '.' pseudodestructorname
            if (ctx.Dot() != null) {
                buftree.append("." + args);
            }
            //postfixexpression '->' pseudodestructorname
            else if (ctx.Arrow() != null)
                buftree.append("->" + args);
            //setclass(ctx, buftree.toString());
            logger.info("pseudodestructorname: " + args);
        }

        if(swTranslate!=null)
            setclass(ctx,swTranslate);
        else
            setclass(ctx, buftree.toString());
        logger.info("exitPostfixexpression final: " + getclass(ctx));
    }

    @Override
    public void exitPrimaryexpression(CPP14Parser.PrimaryexpressionContext ctx) {
        if (ctx.idexpression() != null) {
            String args = getclass(ctx.idexpression());
            if(utility.globalScopeDef.getScope().equals(Utility.globalScope.glbScope.KERNERENTRY)){
                for(int i=0; i<utility.pointerDataAttrList.size(); i++){
                    pointerDataAttr obj  = utility.pointerDataAttrList.get(i);
                    logger.info("find in pointerDataAttrList: " + obj.getVariable()  + " args: " + args +
                            " isAtomOpr: " + directiveDef.isAtomOpr());
                    if(directiveDef.isAtomOpr()) {
                        if (args.equals(atomAttr.getVariable()))
                            logger.info("exitPrimaryexpression find atomic variable:" + args + " keep no change");
                    }
                    else if(args.equals(obj.getVariable())){
                        if(obj.getAttribute().equals("readonly")) {
                            if (obj.getDefinedInCPE())
                                args = obj.getVariable() + "_s";
                            else
                                args = "Para_s->" + obj.getVariable();
                        }
                        else if(obj.getAttribute().equals("inout") || obj.getAttribute().equals("outonly"))
                            args = obj.getVariable() + "_s";

                        logger.info("exitPrimaryexpression find pointerdata: " + args);
                    }
                }
            }
            setclass(ctx, args);
            logger.debug("idexpression: " + args + " scope:" + utility.globalScopeDef.getScope().toString());
        }
        if (ctx.literal() != null) {
            String args = ctx.literal().getText();
            setclass(ctx, args);
            logger.debug("literal: " + args);
        }
        if (ctx.This() != null) {
            String args = ctx.This().getText();
            setclass(ctx, args);
        }
        if (ctx.expression() != null) {
            String args = getclass(ctx.expression());
            StringBuilder buftree = new StringBuilder();
            buftree.append("(" + args + ")");
            setclass(ctx, buftree.toString());
        }
        if (ctx.lambdaexpression() != null) {
            String args = ctx.lambdaexpression().getText();
            setclass(ctx, args);
            logger.info("lambdaexpression: " + args);
        }
    }

    @Override
    public void exitIdexpression(CPP14Parser.IdexpressionContext ctx) {
        if (ctx.unqualifiedid() != null) {
            String args = getclass(ctx.unqualifiedid());
            setclass(ctx, args);
            logger.info("unqualifiedid: " + args);
        }

        if (ctx.qualifiedid() != null) {
            String args = ctx.qualifiedid().getText();
            setclass(ctx, args);
            logger.info("qualifiedid: " + args);
        }
    }

    @Override
    public void exitUnqualifiedid(CPP14Parser.UnqualifiedidContext ctx) {
        if (ctx.templateid() != null) {
            String args = getclass(ctx.templateid());
            setclass(ctx, args);
            logger.info("templateid: " + args);
        }
        if (ctx.operatorfunctionid() != null) {
            String args = ctx.operatorfunctionid().getText();
            setclass(ctx, args);
            logger.info("operatorfunctionid: " + args);
        }
        if (ctx.conversionfunctionid() != null) {
            String args = ctx.conversionfunctionid().getText();
            setclass(ctx, args);
            logger.info("conversionfunctionid: " + args);
        }
        if (ctx.Identifier() != null) {
            String args = ctx.Identifier().getText();

            setclass(ctx, args);
            logger.info("Identifier: " + args);
        }
        if (ctx.literaloperatorid() != null) {
            String args = ctx.literaloperatorid().getText();
            setclass(ctx, args);
            logger.info("literaloperatorid: " + args);
        }
        if (ctx.classname() != null) {
            String args = getclass(ctx.classname());
            StringBuilder buftree = new StringBuilder();
            buftree.append("~" + args);
            setclass(ctx, buftree.toString());
            logger.info("classname: " + args);
        }
        if (ctx.decltypespecifier() != null) {
            String args = ctx.decltypespecifier().getText();
            StringBuilder buftree = new StringBuilder();
            buftree.append("~" + args);
            setclass(ctx, buftree.toString());
            logger.info("decltypespecifier: " + args);
        }
    }

    @Override
    public void exitTemplateid(CPP14Parser.TemplateidContext ctx) {
        if (ctx.simpletemplateid() != null) {
            String args = getclass(ctx.simpletemplateid());
            setclass(ctx, args);
            logger.info("simpletemplateid: " + args);
        }
    }

}
